diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..6383880f5 --- /dev/null +++ b/.clang-format @@ -0,0 +1,51 @@ +--- +# NextUI clang-format configuration +# Based on the existing code style in the project + +BasedOnStyle: LLVM + +# Indentation +UseTab: Always +TabWidth: 4 +IndentWidth: 4 +ContinuationIndentWidth: 4 + +# Line length +ColumnLimit: 120 + +# Braces +BreakBeforeBraces: Linux + +# Spaces +SpaceAfterCStyleCast: false +SpaceBeforeParens: ControlStatements +SpaceBeforeAssignmentOperators: true +SpaceInEmptyParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpacesInCStyleCastParentheses: false + +# Alignment +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true + +# Line breaks +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true + +# Pointer alignment +PointerAlignment: Right + +# Other +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 2 +SortIncludes: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..9cb6d150b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,73 @@ +# Contributing to NextUI + +Thank you for your interest in contributing to NextUI! + +## Code Formatting + +NextUI uses [clang-format](https://clang.llvm.org/docs/ClangFormat.html) to maintain consistent code formatting across all C/C++ source files. + +### Setup + +Clang-format is likely already installed on most development systems. You can verify by running: + +```bash +clang-format --version +``` + +If not installed, you can install it: + +- **Ubuntu/Debian**: `sudo apt-get install clang-format` +- **macOS**: `brew install clang-format` +- **Windows**: Download from [LLVM releases](https://releases.llvm.org/) + +### Formatting Your Code + +Before submitting a pull request, please format your code using clang-format: + +```bash +# Format a single file +clang-format -i path/to/your/file.c + +# Format all C/C++ files in the workspace (excluding _unmaintained) +find workspace -type f \( -name "*.c" -o -name "*.cpp" -o -name "*.h" -o -name "*.hpp" \) | grep -v "_unmaintained" | xargs clang-format -i +``` + +### Checking Formatting + +To check if your files are properly formatted without modifying them: + +```bash +clang-format --dry-run --Werror path/to/your/file.c +``` + +### Configuration + +The clang-format configuration is defined in `.clang-format` at the root of the repository. Key style guidelines: + +- **Indentation**: Tabs (4 spaces wide) +- **Brace Style**: Linux style (opening brace on next line for functions) +- **Line Length**: 120 characters maximum +- **Pointer Alignment**: Right-aligned (`char *ptr` not `char* ptr`) +- **Space After Keywords**: `if (condition)` not `if(condition)` + +### Editor Integration + +Most modern editors and IDEs support clang-format integration: + +- **VS Code**: Install the "C/C++" extension +- **Vim**: Use `vim-clang-format` plugin +- **Emacs**: Use `clang-format.el` +- **CLion/IntelliJ**: Built-in support + +This ensures your code is automatically formatted as you write it. + +## Pull Request Guidelines + +1. Format your code using clang-format before submitting +2. Ensure your changes don't break existing functionality +3. Write clear commit messages +4. Update documentation if needed + +## Questions? + +If you have any questions about contributing, feel free to open an issue or join our [Discord](https://discord.gg/HKd7wqZk3h). diff --git a/README.md b/README.md index 012526ea8..25bf6a88d 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,16 @@ Our community has currated a [list of favorite Paks](https://nextui.loveretro.ga --- +## Contributing + +We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on: + +- Code formatting with clang-format +- Pull request guidelines +- Development setup + +--- + ## Credits [@josegonzalez](https://github.com/josegonzalez) for [minui-keyboard](https://github.com/josegonzalez/minui-keyboard/t) diff --git a/workspace/all/batmon/batmon.c b/workspace/all/batmon/batmon.c index 25761af08..a6945fce3 100644 --- a/workspace/all/batmon/batmon.c +++ b/workspace/all/batmon/batmon.c @@ -27,324 +27,292 @@ int best_session_time = 0; char *device_model = NULL; void register_handler(); -void sigintHandler(int signum) { - switch (signum) - { - case SIGINT: - case SIGTERM: - quit = true; - break; - case SIGSTOP: - is_suspended = true; - break; - case SIGCONT: - is_suspended = false; - break; - default: - break; - } - // reregister - register_handler(); +void sigintHandler(int signum) +{ + switch (signum) { + case SIGINT: + case SIGTERM: + quit = true; + break; + case SIGSTOP: + is_suspended = true; + break; + case SIGCONT: + is_suspended = false; + break; + default: + break; + } + // reregister + register_handler(); } -void register_handler() { - struct sigaction sa; - sa.sa_handler = sigintHandler; +void register_handler() +{ + struct sigaction sa; + sa.sa_handler = sigintHandler; - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGINT); - sigaction(SIGINT, &sa, 0); + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGINT); + sigaction(SIGINT, &sa, 0); - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGTERM); - sigaction(SIGTERM, &sa, 0); + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGTERM); + sigaction(SIGTERM, &sa, 0); - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGSTOP); - sigaction(SIGSTOP, &sa, 0); + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGSTOP); + sigaction(SIGSTOP, &sa, 0); - sigemptyset(&sa.sa_mask); - sigaddset(&sa.sa_mask, SIGCONT); - sigaction(SIGCONT, &sa, 0); + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGCONT); + sigaction(SIGCONT, &sa, 0); } void cleanup(void) { - remove("/tmp/percBat"); + remove("/tmp/percBat"); } void update_current_duration(void) { - sqlite3 *bat_log_db = open_battery_log_db(); - - if (bat_log_db != NULL) - { - const char *sql = "SELECT * FROM bat_activity WHERE device_serial = ? ORDER BY id DESC LIMIT 1;"; - sqlite3_stmt *stmt; - int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); - - if (rc == SQLITE_OK) - { - sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); - rc = sqlite3_step(stmt); - if (rc == SQLITE_ROW) - { - int current_duration = sqlite3_column_int(stmt, 3); - int new_duration = current_duration + battery_current_state_duration; - - const char *update_sql = "UPDATE bat_activity SET duration = ? WHERE id = ?"; - - sqlite3_stmt *update_stmt; - rc = sqlite3_prepare_v2(bat_log_db, update_sql, -1, &update_stmt, 0); - - if (rc == SQLITE_OK) - { - sqlite3_bind_int(update_stmt, 1, new_duration); - sqlite3_bind_int(update_stmt, 2, sqlite3_column_int(stmt, 0)); - - // Exécuter la mise à jour - rc = sqlite3_step(update_stmt); - - battery_current_state_duration = 0; - sqlite3_finalize(stmt); - sqlite3_finalize(update_stmt); - } - } - } - close_battery_log_db(bat_log_db); - } + sqlite3 *bat_log_db = open_battery_log_db(); + + if (bat_log_db != NULL) { + const char *sql = "SELECT * FROM bat_activity WHERE device_serial = ? ORDER BY id DESC LIMIT 1;"; + sqlite3_stmt *stmt; + int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); + + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + int current_duration = sqlite3_column_int(stmt, 3); + int new_duration = current_duration + battery_current_state_duration; + + const char *update_sql = "UPDATE bat_activity SET duration = ? WHERE id = ?"; + + sqlite3_stmt *update_stmt; + rc = sqlite3_prepare_v2(bat_log_db, update_sql, -1, &update_stmt, 0); + + if (rc == SQLITE_OK) { + sqlite3_bind_int(update_stmt, 1, new_duration); + sqlite3_bind_int(update_stmt, 2, sqlite3_column_int(stmt, 0)); + + // Exécuter la mise à jour + rc = sqlite3_step(update_stmt); + + battery_current_state_duration = 0; + sqlite3_finalize(stmt); + sqlite3_finalize(update_stmt); + } + } + } + close_battery_log_db(bat_log_db); + } } void log_new_percentage(int new_bat_value, int is_charging) { - sqlite3 *bat_log_db = open_battery_log_db(); - - if (bat_log_db != NULL) - { - char *sql = sqlite3_mprintf("INSERT INTO bat_activity(device_serial, bat_level, duration, is_charging) VALUES(%Q, %d, %d, %d);", device_model, new_bat_value, 0, is_charging); - sqlite3_exec(bat_log_db, sql, NULL, NULL, NULL); - sqlite3_free(sql); - - // FILO logic - sqlite3_stmt *stmt; - const char *count_sql = "SELECT COUNT(id) FROM bat_activity"; - - int count = 0; - - if (sqlite3_prepare_v2(bat_log_db, count_sql, -1, &stmt, NULL) == SQLITE_OK) - { - if (sqlite3_step(stmt) == SQLITE_ROW) - { - count = sqlite3_column_int(stmt, 0); - } - sqlite3_finalize(stmt); - } - - if (count > FILO_MIN_SIZE) - { - // Deletion of the 1st entry - const char *delete_sql = "DELETE FROM bat_activity WHERE id = (SELECT MIN(id) FROM bat_activity);"; - sqlite3_prepare_v2(bat_log_db, delete_sql, -1, &stmt, 0); - sqlite3_step(stmt); - sqlite3_finalize(stmt); - } - } - close_battery_log_db(bat_log_db); + sqlite3 *bat_log_db = open_battery_log_db(); + + if (bat_log_db != NULL) { + char *sql = sqlite3_mprintf( + "INSERT INTO bat_activity(device_serial, bat_level, duration, is_charging) VALUES(%Q, %d, %d, %d);", + device_model, new_bat_value, 0, is_charging); + sqlite3_exec(bat_log_db, sql, NULL, NULL, NULL); + sqlite3_free(sql); + + // FILO logic + sqlite3_stmt *stmt; + const char *count_sql = "SELECT COUNT(id) FROM bat_activity"; + + int count = 0; + + if (sqlite3_prepare_v2(bat_log_db, count_sql, -1, &stmt, NULL) == SQLITE_OK) { + if (sqlite3_step(stmt) == SQLITE_ROW) { + count = sqlite3_column_int(stmt, 0); + } + sqlite3_finalize(stmt); + } + + if (count > FILO_MIN_SIZE) { + // Deletion of the 1st entry + const char *delete_sql = "DELETE FROM bat_activity WHERE id = (SELECT MIN(id) FROM bat_activity);"; + sqlite3_prepare_v2(bat_log_db, delete_sql, -1, &stmt, 0); + sqlite3_step(stmt); + sqlite3_finalize(stmt); + } + } + close_battery_log_db(bat_log_db); } int get_current_session_time(void) { - int current_session_duration = 0; - - sqlite3 *bat_log_db = open_battery_log_db(); - - if (bat_log_db != NULL) - { - const char *sql = "SELECT * FROM bat_activity WHERE device_serial = ? AND is_charging = 1 ORDER BY id DESC LIMIT 1;"; - sqlite3_stmt *stmt; - int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); - - if (rc == SQLITE_OK) - { - - sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); - rc = sqlite3_step(stmt); - if (rc == SQLITE_ROW) - { - - sqlite3_stmt *stmt_sum; - const char *query_sum = "SELECT SUM(duration) FROM bat_activity WHERE device_serial = ? AND id > ?;"; - rc = sqlite3_prepare_v2(bat_log_db, query_sum, -1, &stmt_sum, NULL); - if (rc == SQLITE_OK) - { - sqlite3_bind_text(stmt_sum, 1, device_model, -1, SQLITE_STATIC); - sqlite3_bind_int(stmt_sum, 2, sqlite3_column_int(stmt, 0)); - while ((rc = sqlite3_step(stmt_sum)) == SQLITE_ROW) - { - current_session_duration = sqlite3_column_int(stmt_sum, 0); - } - } - sqlite3_finalize(stmt_sum); - } - } - sqlite3_finalize(stmt); - } - close_battery_log_db(bat_log_db); - - return current_session_duration; + int current_session_duration = 0; + + sqlite3 *bat_log_db = open_battery_log_db(); + + if (bat_log_db != NULL) { + const char *sql = + "SELECT * FROM bat_activity WHERE device_serial = ? AND is_charging = 1 ORDER BY id DESC LIMIT 1;"; + sqlite3_stmt *stmt; + int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); + + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + sqlite3_stmt *stmt_sum; + const char *query_sum = "SELECT SUM(duration) FROM bat_activity WHERE device_serial = ? AND id > ?;"; + rc = sqlite3_prepare_v2(bat_log_db, query_sum, -1, &stmt_sum, NULL); + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt_sum, 1, device_model, -1, SQLITE_STATIC); + sqlite3_bind_int(stmt_sum, 2, sqlite3_column_int(stmt, 0)); + while ((rc = sqlite3_step(stmt_sum)) == SQLITE_ROW) { + current_session_duration = sqlite3_column_int(stmt_sum, 0); + } + } + sqlite3_finalize(stmt_sum); + } + } + sqlite3_finalize(stmt); + } + close_battery_log_db(bat_log_db); + + return current_session_duration; } int set_best_session_time(int best_session) { - int is_success = 0; - - sqlite3* bat_log_db = open_battery_log_db(); - - if (bat_log_db != NULL) - { - const char *sql = "SELECT * FROM device_specifics WHERE device_serial = ? ORDER BY id LIMIT 1;"; - sqlite3_stmt *stmt; - int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); - - if (rc == SQLITE_OK) - { - sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); - rc = sqlite3_step(stmt); - if (rc == SQLITE_ROW) - { - const char *update_sql = "UPDATE device_specifics SET best_session = ? WHERE id = ?"; - - sqlite3_stmt *update_stmt; - rc = sqlite3_prepare_v2(bat_log_db, update_sql, -1, &update_stmt, 0); - - if (rc == SQLITE_OK) - { - sqlite3_bind_int(update_stmt, 1, best_session); - sqlite3_bind_int(update_stmt, 2, sqlite3_column_int(stmt, 0)); - - // Exécuter la mise à jour - rc = sqlite3_step(update_stmt); - - sqlite3_finalize(stmt); - sqlite3_finalize(update_stmt); - is_success = 1; - } - } - } - close_battery_log_db(bat_log_db); - } - - return is_success; + int is_success = 0; + + sqlite3 *bat_log_db = open_battery_log_db(); + + if (bat_log_db != NULL) { + const char *sql = "SELECT * FROM device_specifics WHERE device_serial = ? ORDER BY id LIMIT 1;"; + sqlite3_stmt *stmt; + int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); + + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + const char *update_sql = "UPDATE device_specifics SET best_session = ? WHERE id = ?"; + + sqlite3_stmt *update_stmt; + rc = sqlite3_prepare_v2(bat_log_db, update_sql, -1, &update_stmt, 0); + + if (rc == SQLITE_OK) { + sqlite3_bind_int(update_stmt, 1, best_session); + sqlite3_bind_int(update_stmt, 2, sqlite3_column_int(stmt, 0)); + + // Exécuter la mise à jour + rc = sqlite3_step(update_stmt); + + sqlite3_finalize(stmt); + sqlite3_finalize(update_stmt); + is_success = 1; + } + } + } + close_battery_log_db(bat_log_db); + } + + return is_success; } int main(int argc, char *argv[]) { - device_model = PLAT_getModel(); - sqlite3 *bat_log_db = open_battery_log_db(); - if(bat_log_db != NULL) { - best_session_time = get_best_session_time(bat_log_db, device_model); - close_battery_log_db(bat_log_db); - } - - FILE *fp; - int old_percentage = -1; - int lowest_percentage_after_charge = 500; - atexit(cleanup); - register_handler(); - int ticks = CHECK_BATTERY_TIMEOUT_S; - - struct { - int is_charging; - int charge; - } pwr = {0}; - bool was_charging = false; - - while (!quit) - { - PLAT_getBatteryStatusFine(&pwr.is_charging, &pwr.charge); - if (pwr.is_charging) - { - if (!was_charging) - { - // Charging just started - lowest_percentage_after_charge = 500; // Reset lowest percentage before charge - was_charging = true; - update_current_duration(); - - int session_time = get_current_session_time(); - LOG_debug("Charging detected - Previous session duration = %d\n", session_time); - - if (session_time > best_session_time) - { - LOG_debug("Best session duration\n", 1); - set_best_session_time(session_time); - best_session_time = session_time; - } - log_new_percentage(pwr.charge, was_charging); - } - } - else if (was_charging) - { - // Charging just stopped - was_charging = false; - lowest_percentage_after_charge = 500; // Reset lowest percentage after charge - - LOG_debug( - "Charging stopped: suspended = %d, perc = %d\n", - is_suspended, pwr.charge); - - update_current_duration(); - log_new_percentage(pwr.charge, was_charging); - } - - if (!is_suspended) - { - if (ticks >= CHECK_BATTERY_TIMEOUT_S) - { - LOG_debug( - "battery check: suspended = %d, perc = %d\n", - is_suspended, pwr.charge); - - ticks = -1; - } - - if (pwr.charge != old_percentage) - { - // This statement is not englobed in the previous one - // in order to be launched once when batmon starts - LOG_debug( - "saving percBat: suspended = %d, perc = %d\n", - is_suspended, pwr.charge); - old_percentage = pwr.charge; - // Save battery percentage to file - if ((fp = fopen("/tmp/percBat", "w+"))) { - fprintf(fp, "%d", pwr.charge); - fflush(fp); - fsync(fileno(fp)); - fclose(fp); - } - // Current battery state duration addition - update_current_duration(); - // New battery percentage entry - log_new_percentage(pwr.charge, was_charging); - } - } - else - { - ticks = -1; - } - - if (battery_current_state_duration > MAX_DURATION_BEFORE_UPDATE) - update_current_duration(); - - sleep(1); - battery_current_state_duration++; - ticks++; - } - - LOG_debug("caught SIGTERM/SIGINT, quitting\n"); - - // Current battery state duration addition - update_current_duration(); - return EXIT_SUCCESS; + device_model = PLAT_getModel(); + sqlite3 *bat_log_db = open_battery_log_db(); + if (bat_log_db != NULL) { + best_session_time = get_best_session_time(bat_log_db, device_model); + close_battery_log_db(bat_log_db); + } + + FILE *fp; + int old_percentage = -1; + int lowest_percentage_after_charge = 500; + atexit(cleanup); + register_handler(); + int ticks = CHECK_BATTERY_TIMEOUT_S; + + struct { + int is_charging; + int charge; + } pwr = {0}; + bool was_charging = false; + + while (!quit) { + PLAT_getBatteryStatusFine(&pwr.is_charging, &pwr.charge); + if (pwr.is_charging) { + if (!was_charging) { + // Charging just started + lowest_percentage_after_charge = 500; // Reset lowest percentage before charge + was_charging = true; + update_current_duration(); + + int session_time = get_current_session_time(); + LOG_debug("Charging detected - Previous session duration = %d\n", session_time); + + if (session_time > best_session_time) { + LOG_debug("Best session duration\n", 1); + set_best_session_time(session_time); + best_session_time = session_time; + } + log_new_percentage(pwr.charge, was_charging); + } + } else if (was_charging) { + // Charging just stopped + was_charging = false; + lowest_percentage_after_charge = 500; // Reset lowest percentage after charge + + LOG_debug("Charging stopped: suspended = %d, perc = %d\n", is_suspended, pwr.charge); + + update_current_duration(); + log_new_percentage(pwr.charge, was_charging); + } + + if (!is_suspended) { + if (ticks >= CHECK_BATTERY_TIMEOUT_S) { + LOG_debug("battery check: suspended = %d, perc = %d\n", is_suspended, pwr.charge); + + ticks = -1; + } + + if (pwr.charge != old_percentage) { + // This statement is not englobed in the previous one + // in order to be launched once when batmon starts + LOG_debug("saving percBat: suspended = %d, perc = %d\n", is_suspended, pwr.charge); + old_percentage = pwr.charge; + // Save battery percentage to file + if ((fp = fopen("/tmp/percBat", "w+"))) { + fprintf(fp, "%d", pwr.charge); + fflush(fp); + fsync(fileno(fp)); + fclose(fp); + } + // Current battery state duration addition + update_current_duration(); + // New battery percentage entry + log_new_percentage(pwr.charge, was_charging); + } + } else { + ticks = -1; + } + + if (battery_current_state_duration > MAX_DURATION_BEFORE_UPDATE) + update_current_duration(); + + sleep(1); + battery_current_state_duration++; + ticks++; + } + + LOG_debug("caught SIGTERM/SIGINT, quitting\n"); + + // Current battery state duration addition + update_current_duration(); + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/workspace/all/battery/battery.c b/workspace/all/battery/battery.c index 34bb20a9e..be92d807b 100644 --- a/workspace/all/battery/battery.c +++ b/workspace/all/battery/battery.c @@ -29,57 +29,54 @@ // 1:1 #define GRAPH_SEGMENT_HIGH 1800 -struct GraphLayout -{ - int graph_display_size_x; - int graph_display_size_y; - int graph_display_start_x; - int graph_display_start_y; +struct GraphLayout { + int graph_display_size_x; + int graph_display_size_y; + int graph_display_start_x; + int graph_display_start_y; - int label_y; - int label1_x; - int label2_x; - int label3_x; - int label4_x; + int label_y; + int label1_x; + int label2_x; + int label3_x; + int label4_x; - int sub_title_x; - int sub_title_y; + int sub_title_x; + int sub_title_y; - int label_session_x; - int label_session_y; + int label_session_x; + int label_session_y; - int label_current_x; - int label_current_y; + int label_current_x; + int label_current_y; - int label_left_x; - int label_left_y; + int label_left_x; + int label_left_y; - int label_best_x; - int label_best_y; + int label_best_x; + int label_best_y; - int label_size_x; - int label_size_y; + int label_size_x; + int label_size_y; - int icon_x; - int icon1_y; - int icon2_y; - int icon3_y; - int icon4_y; + int icon_x; + int icon1_y; + int icon2_y; + int icon3_y; + int icon4_y; - int graph_max_size; + int graph_max_size; }; -typedef struct -{ - int pixel_height; - bool is_charging; - bool is_estimated; +typedef struct { + int pixel_height; + bool is_charging; + bool is_estimated; } GraphSpot; -struct Graph -{ - struct GraphLayout layout; - GraphSpot *graphic; // needs to be >= GRAPH_MAX_FULL_PAGES * screen_width +struct Graph { + struct GraphLayout layout; + GraphSpot *graphic; // needs to be >= GRAPH_MAX_FULL_PAGES * screen_width } graph = {0}; // One page in seconds @@ -113,15 +110,14 @@ static char session_best[10]; static void sigHandler(int sig) { - switch (sig) - { - case SIGINT: - case SIGTERM: - quit = true; - break; - default: - break; - } + switch (sig) { + case SIGINT: + case SIGTERM: + quit = true; + break; + default: + break; + } } static SDL_Surface *screen; @@ -131,445 +127,424 @@ sqlite3 *bat_log_db = NULL; void secondsToHoursMinutes(int seconds, char *output) { - int hours = seconds / 3600; - int minutes = (seconds % 3600) / 60; - sprintf(output, "%dh%02d", hours, minutes); + int hours = seconds / 3600; + int minutes = (seconds % 3600) / 60; + sprintf(output, "%dh%02d", hours, minutes); } void drawLine(int x1, int y1, int x2, int y2, Uint32 color) { - int dx, dy, sx, sy, err, e2; - - dx = abs(x2 - x1); - dy = abs(y2 - y1); - - if (x1 < x2) - { - sx = 1; - } - else - { - sx = -1; - } - - if (y1 < y2) - { - sy = 1; - } - else - { - sy = -1; - } - - err = dx - dy; - - while (1) - { - SDL_Rect pixel = {x1, y1, SCALE1(1), SCALE1(1)}; - SDL_FillRect(screen, &pixel, color); - - if (x1 == x2 && y1 == y2) - { - break; - } - - e2 = 2 * err; - - if (e2 > -dy) - { - err -= dy; - x1 += sx; - } - - if (e2 < dx) - { - err += dx; - y1 += sy; - } - } + int dx, dy, sx, sy, err, e2; + + dx = abs(x2 - x1); + dy = abs(y2 - y1); + + if (x1 < x2) { + sx = 1; + } else { + sx = -1; + } + + if (y1 < y2) { + sy = 1; + } else { + sy = -1; + } + + err = dx - dy; + + while (1) { + SDL_Rect pixel = {x1, y1, SCALE1(1), SCALE1(1)}; + SDL_FillRect(screen, &pixel, color); + + if (x1 == x2 && y1 == y2) { + break; + } + + e2 = 2 * err; + + if (e2 > -dy) { + err -= dy; + x1 += sx; + } + + if (e2 < dx) { + err += dx; + y1 += sy; + } + } } int _renderText(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rect, bool right_align) { - int text_width = 0; - SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, text, color); - if (textSurface != NULL) - { - text_width = textSurface->w; - if (right_align) - SDL_BlitSurface(textSurface, NULL, screen, &(SDL_Rect){rect->x - textSurface->w, rect->y, rect->w, rect->h}); - else - SDL_BlitSurface(textSurface, NULL, screen, rect); - SDL_FreeSurface(textSurface); - } - return text_width; + int text_width = 0; + SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, text, color); + if (textSurface != NULL) { + text_width = textSurface->w; + if (right_align) + SDL_BlitSurface(textSurface, NULL, screen, + &(SDL_Rect){rect->x - textSurface->w, rect->y, rect->w, rect->h}); + else + SDL_BlitSurface(textSurface, NULL, screen, rect); + SDL_FreeSurface(textSurface); + } + return text_width; } int renderText(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rect) { - return _renderText(text, font, color, rect, false); + return _renderText(text, font, color, rect, false); } int renderTextAlignRight(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rect) { - return _renderText(text, font, color, rect, true); + return _renderText(text, font, color, rect, true); } void switch_zoom_profile(int segment_duration) { - // TODO: no reason this cant be dynamic - switch (segment_duration) - { - case GRAPH_SEGMENT_LOW: - // A segment is 120 minutes - sprintf(label[0], "%s", "4h"); - sprintf(label[1], "%s", "8h"); - sprintf(label[2], "%s", "12h"); - sprintf(label[3], "%s", "16h"); - break; - case GRAPH_SEGMENT_MED: - // A segment is 60 minutes - sprintf(label[0], "%s", "2h"); - sprintf(label[1], "%s", "4h"); - sprintf(label[2], "%s", "6h"); - sprintf(label[3], "%s", "8h"); - break; - case GRAPH_SEGMENT_HIGH: - // A segment is 30 minutes - sprintf(label[0], "%s", "1h"); - sprintf(label[1], "%s", "2h"); - sprintf(label[2], "%s", "3h"); - sprintf(label[3], "%s", "4h"); - break; - default: - sprintf(label[0], "%s", ""); - sprintf(label[1], "%s", ""); - sprintf(label[2], "%s", ""); - sprintf(label[3], "%s", ""); - break; - } + // TODO: no reason this cant be dynamic + switch (segment_duration) { + case GRAPH_SEGMENT_LOW: + // A segment is 120 minutes + sprintf(label[0], "%s", "4h"); + sprintf(label[1], "%s", "8h"); + sprintf(label[2], "%s", "12h"); + sprintf(label[3], "%s", "16h"); + break; + case GRAPH_SEGMENT_MED: + // A segment is 60 minutes + sprintf(label[0], "%s", "2h"); + sprintf(label[1], "%s", "4h"); + sprintf(label[2], "%s", "6h"); + sprintf(label[3], "%s", "8h"); + break; + case GRAPH_SEGMENT_HIGH: + // A segment is 30 minutes + sprintf(label[0], "%s", "1h"); + sprintf(label[1], "%s", "2h"); + sprintf(label[2], "%s", "3h"); + sprintf(label[3], "%s", "4h"); + break; + default: + sprintf(label[0], "%s", ""); + sprintf(label[1], "%s", ""); + sprintf(label[2], "%s", ""); + sprintf(label[3], "%s", ""); + break; + } } int battery_to_pixel(int battery_perc) { - // Converts a battery percentage to a pixel coordinate - int y = (int)((graph.layout.graph_display_size_y * battery_perc) / 100); - - if ((y < 0) || (y > graph.layout.graph_display_size_y)) - { - return -1; - } - else - { - return y; - } + // Converts a battery percentage to a pixel coordinate + int y = (int)((graph.layout.graph_display_size_y * battery_perc) / 100); + + if ((y < 0) || (y > graph.layout.graph_display_size_y)) { + return -1; + } else { + return y; + } } int duration_to_pixel(int duration) { - // Convert a duration to a number of pixel - return (int)((graph.layout.graph_display_size_x * duration) / GRAPH_DISPLAY_DURATION); + // Convert a duration to a number of pixel + return (int)((graph.layout.graph_display_size_x * duration) / GRAPH_DISPLAY_DURATION); } void compute_graph(void) { - int total_duration = 0; - int previous_index = graph.layout.graph_max_size - 1; - bool is_estimation_computed = false; - - bat_log_db = open_battery_log_db(); - secondsToHoursMinutes(get_best_session_time(bat_log_db, device_model), session_best); - - if (bat_log_db != NULL) - { - const char *sql = "SELECT * FROM bat_activity WHERE device_serial = ? ORDER BY id DESC;"; - sqlite3_stmt *stmt; - int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); - - if (rc == SQLITE_OK) - { - sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); - bool b_quit = false; - - while ((sqlite3_step(stmt) == SQLITE_ROW) && (!b_quit)) - { - - int bat_perc = sqlite3_column_int(stmt, 2); - int duration = sqlite3_column_int(stmt, 3); - bool is_charging = sqlite3_column_int(stmt, 4); - - if (total_duration == 0) - { - sprintf(current_percentage, "%d%%", bat_perc); - } - - current_index = (graph.layout.graph_max_size - 1) - duration_to_pixel(total_duration); - graph.graphic[current_index].is_charging = is_charging; - - if (bat_perc > 100) - bat_perc = 100; - - graph.graphic[current_index].pixel_height = battery_to_pixel(bat_perc); - - int segment = previous_index - current_index; - if (segment > 1) - { - for (int i = 1; i < segment; i++) - { - graph.graphic[current_index + i].pixel_height = graph.graphic[previous_index].pixel_height; - graph.graphic[current_index + i].is_charging = graph.graphic[previous_index].is_charging; - } - } - - if ((is_charging) && (!is_estimation_computed)) - { - secondsToHoursMinutes(total_duration, session_duration); - if (previous_index < (graph.layout.graph_max_size - duration_to_pixel(GRAPH_MIN_SESSION_FOR_ESTIMATION))) - { - float slope = (float)(graph.graphic[graph.layout.graph_max_size - 1].pixel_height - graph.graphic[previous_index].pixel_height) / (float)(graph.layout.graph_max_size - 1 - previous_index); - - if (slope < 0) - { - - estimation_line_size = (int)-(graph.graphic[graph.layout.graph_max_size - 1].pixel_height) / slope; - - int estimated_playtime = (int)(estimation_line_size)*GRAPH_DISPLAY_DURATION / graph.layout.graph_display_size_x; - - if (estimated_playtime < GRAPH_MAX_PLAUSIBLE_ESTIMATION) - { - secondsToHoursMinutes(estimated_playtime, session_left); - // shift of the existing logs to make room for the estimation line - int room_to_make = estimation_line_size + GRAPH_ESTIMATED_LINE_GAP; - if (current_index - room_to_make >= 0) - { - for (int i = current_index; i < graph.layout.graph_max_size; i++) - { - graph.graphic[i - room_to_make].pixel_height = graph.graphic[i].pixel_height; - graph.graphic[i - room_to_make].is_charging = graph.graphic[i].is_charging; - graph.graphic[i].pixel_height = 0; - graph.graphic[i].is_charging = false; - } - } - total_duration += estimated_playtime + (int)(GRAPH_ESTIMATED_LINE_GAP)*GRAPH_DISPLAY_DURATION / graph.layout.graph_display_size_x; - current_index -= room_to_make; - previous_index -= room_to_make; - begining_session_index = previous_index; - for (int x = (graph.layout.graph_max_size - room_to_make); x < graph.layout.graph_max_size; x++) - { - int y = graph.graphic[previous_index].pixel_height + (int)(slope * (x - previous_index)); - if (y > 0) - { - graph.graphic[x].pixel_height = y; - graph.graphic[x].is_estimated = true; - } - else - break; - } - } - else - { - estimation_line_size = 0; - estimated_playtime = 0; - } - } - } - - is_estimation_computed = true; - } - - total_duration += duration; - if (duration_to_pixel(total_duration) > graph.layout.graph_max_size) - b_quit = true; - - previous_index = current_index; - } - } - sqlite3_finalize(stmt); - close_battery_log_db(bat_log_db); - } + int total_duration = 0; + int previous_index = graph.layout.graph_max_size - 1; + bool is_estimation_computed = false; + + bat_log_db = open_battery_log_db(); + secondsToHoursMinutes(get_best_session_time(bat_log_db, device_model), session_best); + + if (bat_log_db != NULL) { + const char *sql = "SELECT * FROM bat_activity WHERE device_serial = ? ORDER BY id DESC;"; + sqlite3_stmt *stmt; + int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); + + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, device_model, -1, SQLITE_STATIC); + bool b_quit = false; + + while ((sqlite3_step(stmt) == SQLITE_ROW) && (!b_quit)) { + int bat_perc = sqlite3_column_int(stmt, 2); + int duration = sqlite3_column_int(stmt, 3); + bool is_charging = sqlite3_column_int(stmt, 4); + + if (total_duration == 0) { + sprintf(current_percentage, "%d%%", bat_perc); + } + + current_index = (graph.layout.graph_max_size - 1) - duration_to_pixel(total_duration); + graph.graphic[current_index].is_charging = is_charging; + + if (bat_perc > 100) + bat_perc = 100; + + graph.graphic[current_index].pixel_height = battery_to_pixel(bat_perc); + + int segment = previous_index - current_index; + if (segment > 1) { + for (int i = 1; i < segment; i++) { + graph.graphic[current_index + i].pixel_height = graph.graphic[previous_index].pixel_height; + graph.graphic[current_index + i].is_charging = graph.graphic[previous_index].is_charging; + } + } + + if ((is_charging) && (!is_estimation_computed)) { + secondsToHoursMinutes(total_duration, session_duration); + if (previous_index < + (graph.layout.graph_max_size - duration_to_pixel(GRAPH_MIN_SESSION_FOR_ESTIMATION))) { + float slope = (float)(graph.graphic[graph.layout.graph_max_size - 1].pixel_height - + graph.graphic[previous_index].pixel_height) / + (float)(graph.layout.graph_max_size - 1 - previous_index); + + if (slope < 0) { + estimation_line_size = + (int)-(graph.graphic[graph.layout.graph_max_size - 1].pixel_height) / slope; + + int estimated_playtime = + (int)(estimation_line_size)*GRAPH_DISPLAY_DURATION / graph.layout.graph_display_size_x; + + if (estimated_playtime < GRAPH_MAX_PLAUSIBLE_ESTIMATION) { + secondsToHoursMinutes(estimated_playtime, session_left); + // shift of the existing logs to make room for the estimation line + int room_to_make = estimation_line_size + GRAPH_ESTIMATED_LINE_GAP; + if (current_index - room_to_make >= 0) { + for (int i = current_index; i < graph.layout.graph_max_size; i++) { + graph.graphic[i - room_to_make].pixel_height = graph.graphic[i].pixel_height; + graph.graphic[i - room_to_make].is_charging = graph.graphic[i].is_charging; + graph.graphic[i].pixel_height = 0; + graph.graphic[i].is_charging = false; + } + } + total_duration += + estimated_playtime + (int)(GRAPH_ESTIMATED_LINE_GAP)*GRAPH_DISPLAY_DURATION / + graph.layout.graph_display_size_x; + current_index -= room_to_make; + previous_index -= room_to_make; + begining_session_index = previous_index; + for (int x = (graph.layout.graph_max_size - room_to_make); + x < graph.layout.graph_max_size; x++) { + int y = graph.graphic[previous_index].pixel_height + + (int)(slope * (x - previous_index)); + if (y > 0) { + graph.graphic[x].pixel_height = y; + graph.graphic[x].is_estimated = true; + } else + break; + } + } else { + estimation_line_size = 0; + estimated_playtime = 0; + } + } + } + + is_estimation_computed = true; + } + + total_duration += duration; + if (duration_to_pixel(total_duration) > graph.layout.graph_max_size) + b_quit = true; + + previous_index = current_index; + } + } + sqlite3_finalize(stmt); + close_battery_log_db(bat_log_db); + } } -void drawBatteryIcon(int percent, SDL_Rect dst) { - // taken from GFX_blitBattery - - int x = dst.x; - int y = dst.y; - //SDL_Rect rect = asset_rects[ASSET_BATTERY]; - SDL_Rect rect = (SDL_Rect){SCALE4(47,51,17,10)}; - GFX_blitAsset(ASSET_BATTERY, NULL, screen, &(SDL_Rect){x,y}); - //rect = asset_rects[ASSET_BATTERY_FILL]; - rect = (SDL_Rect){SCALE4(81,33,12,6)}; - SDL_Rect clip = rect; - clip.w *= percent; - clip.w /= 100; - if (clip.w<=0) return; - clip.x = rect.w - clip.w; - clip.y = 0; - - GFX_blitAsset(ASSET_BATTERY_FILL, &clip, screen, &(SDL_Rect){x+SCALE1(3)+clip.x,y+SCALE1(2)}); +void drawBatteryIcon(int percent, SDL_Rect dst) +{ + // taken from GFX_blitBattery + + int x = dst.x; + int y = dst.y; + // SDL_Rect rect = asset_rects[ASSET_BATTERY]; + SDL_Rect rect = (SDL_Rect){SCALE4(47, 51, 17, 10)}; + GFX_blitAsset(ASSET_BATTERY, NULL, screen, &(SDL_Rect){x, y}); + // rect = asset_rects[ASSET_BATTERY_FILL]; + rect = (SDL_Rect){SCALE4(81, 33, 12, 6)}; + SDL_Rect clip = rect; + clip.w *= percent; + clip.w /= 100; + if (clip.w <= 0) + return; + clip.x = rect.w - clip.w; + clip.y = 0; + + GFX_blitAsset(ASSET_BATTERY_FILL, &clip, screen, &(SDL_Rect){x + SCALE1(3) + clip.x, y + SCALE1(2)}); } void renderPage() { - const struct SDL_Point tl = {graph.layout.graph_display_start_x, graph.layout.graph_display_start_y}; - const struct SDL_Point br = {graph.layout.graph_display_start_x + graph.layout.graph_display_size_x, graph.layout.graph_display_start_y + graph.layout.graph_display_size_y}; - const int grid_step_x = 2 * (int)(graph.layout.graph_display_size_x / GRAPH_SEGMENTS); // every second "segment" - const int grid_step_y = graph.layout.graph_display_size_y / 4; - - // grid verticals - for (int x = tl.x; x <= br.x; x+= grid_step_x) - drawLine(x, tl.y, x, br.y, RGB_DARK_GRAY); - drawLine(br.x, tl.y, br.x, br.y, RGB_DARK_GRAY); // close the last segment early - // grid horizontals - for (int y = tl.y; y <= br.y; y += grid_step_y) - drawLine(tl.x, y, br.x, y, RGB_DARK_GRAY); - - switch (current_zoom) - { - case 0: - segment_duration = GRAPH_SEGMENT_LOW; - break; - case 1: - segment_duration = GRAPH_SEGMENT_MED; - break; - case 2: - segment_duration = GRAPH_SEGMENT_HIGH; - break; - default: - segment_duration = GRAPH_SEGMENT_MED; - break; - } - - if (estimation_line_size == 0) - current_index = graph.layout.graph_max_size - (graph.layout.graph_display_size_x * (int)(segment_duration / GRAPH_SEGMENT_HIGH)); - else - current_index = begining_session_index; - - current_index -= (int)(current_page * (graph.layout.graph_display_size_x * (int)(segment_duration / GRAPH_SEGMENT_HIGH)) / GRAPH_PAGE_SCROLL_SMOOTHNESS); - - if (current_index < 0) - current_index = 0; - - switch_zoom_profile(segment_duration); - - // x axis labels - renderText(label[0], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label1_x, graph.layout.label_y, 32, 32}); - renderText(label[1], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label2_x, graph.layout.label_y, 32, 32}); - renderText(label[2], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label3_x, graph.layout.label_y, 32, 32}); - renderText(label[3], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label4_x, graph.layout.label_y, 32, 32}); - - // y axis "labels" - drawBatteryIcon(100, (SDL_Rect){graph.layout.icon_x, graph.layout.icon1_y}); - drawBatteryIcon(66, (SDL_Rect){graph.layout.icon_x, graph.layout.icon2_y}); - drawBatteryIcon(33, (SDL_Rect){graph.layout.icon_x, graph.layout.icon3_y}); - drawBatteryIcon(0, (SDL_Rect){graph.layout.icon_x, graph.layout.icon4_y}); - - char text_line[255]; - sprintf(text_line, "Since Charge: %s", session_duration); - renderText(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_session_x, graph.layout.label_session_y, graph.layout.label_size_x, graph.layout.label_size_y}); - - sprintf(text_line, "Current: %s", current_percentage); - renderText(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_current_x, graph.layout.label_current_y, graph.layout.label_size_x, graph.layout.label_size_y}); - - sprintf(text_line, "Remaining: %s", session_left); - renderTextAlignRight(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_left_x, graph.layout.label_left_y, graph.layout.label_size_x, graph.layout.label_size_y}); - - sprintf(text_line, "Longest: %s", session_best); - renderTextAlignRight(text_line, font.medium, COLOR_WHITE, &(SDL_Rect){graph.layout.label_best_x, graph.layout.label_best_y, graph.layout.label_size_x, graph.layout.label_size_y}); - - int half_line_width = (int)(GRAPH_LINE_WIDTH) / 2; - - Uint32 white_pixel_color = RGB_GRAY; - Uint32 red_pixel_color = RGB_WHITE; - Uint32 blue_pixel_color = RGB_LIGHT_GRAY; - Uint32 pixel_color = white_pixel_color; - - // monochrome is more MinUI, but some colours are nice - const bool ilikeitcolourful = true; - if(ilikeitcolourful) { - white_pixel_color = SDL_MapRGB(screen->format, 255, 255, 255); - red_pixel_color = SDL_MapRGB(screen->format, 255, 170, 170); - blue_pixel_color = SDL_MapRGB(screen->format, 89, 167, 255); - pixel_color = white_pixel_color; - } - - int x; - int y; - int x_end = 0; - int y_end = 0; - - int zoom_level = (int)segment_duration / GRAPH_SEGMENT_HIGH; - - if (SDL_LockSurface(screen) == 0) - { - // some constants to make it more readable - const int graph_display_right = graph.layout.graph_display_size_x + graph.layout.graph_display_start_x; - const int graph_display_bottom = graph.layout.graph_display_size_y + graph.layout.graph_display_start_y; - - for (int i = 0; i < graph.layout.graph_max_size - current_index; i += zoom_level) - { - x = graph.layout.graph_display_start_x + (int)(i / zoom_level); - y = graph.graphic[i + current_index].pixel_height; - - bool is_charging = graph.graphic[i + current_index].is_charging; - bool is_estimated = graph.graphic[i + current_index].is_estimated; - // if ((!is_charging) - if ((!is_charging) && (!is_estimated)) - pixel_color = white_pixel_color; - else if (is_charging) - pixel_color = red_pixel_color; - else if (is_estimated) - { - pixel_color = blue_pixel_color; - // magic numbers everywhere... - if (y < 5 && x < graph_display_right) - { - x_end = x - 12; - y_end = graph_display_bottom - 45; - } - } - - if (x < graph_display_right && y > 0) - { - // Actual graph line - if (half_line_width >= 0) - { - for (int k = -half_line_width; k <= half_line_width; k++) - { - int index = (graph_display_bottom - y + k) * screen->pitch + x * screen->format->BytesPerPixel; - *((Uint32 *)((Uint8 *)screen->pixels + index)) = pixel_color; - } - } - - // Area under the graph - if ((x % GRAPH_BACKGROUND_OPACITY) == 0) - { - for (int k = y; k > 0; k--) - { - if ((k % GRAPH_BACKGROUND_OPACITY) == 0) - { - int index = (graph_display_bottom - k) * screen->pitch + x * screen->format->BytesPerPixel; - *((Uint32 *)((Uint8 *)screen->pixels + index)) = pixel_color; - } - } - } - } - } - SDL_UnlockSurface(screen); - if (x_end != 0) - GFX_blitAsset(ASSET_BATTERY_LOW, NULL, screen, &(SDL_Rect){x_end, y_end}); - } + const struct SDL_Point tl = {graph.layout.graph_display_start_x, graph.layout.graph_display_start_y}; + const struct SDL_Point br = {graph.layout.graph_display_start_x + graph.layout.graph_display_size_x, + graph.layout.graph_display_start_y + graph.layout.graph_display_size_y}; + const int grid_step_x = 2 * (int)(graph.layout.graph_display_size_x / GRAPH_SEGMENTS); // every second "segment" + const int grid_step_y = graph.layout.graph_display_size_y / 4; + + // grid verticals + for (int x = tl.x; x <= br.x; x += grid_step_x) + drawLine(x, tl.y, x, br.y, RGB_DARK_GRAY); + drawLine(br.x, tl.y, br.x, br.y, RGB_DARK_GRAY); // close the last segment early + // grid horizontals + for (int y = tl.y; y <= br.y; y += grid_step_y) + drawLine(tl.x, y, br.x, y, RGB_DARK_GRAY); + + switch (current_zoom) { + case 0: + segment_duration = GRAPH_SEGMENT_LOW; + break; + case 1: + segment_duration = GRAPH_SEGMENT_MED; + break; + case 2: + segment_duration = GRAPH_SEGMENT_HIGH; + break; + default: + segment_duration = GRAPH_SEGMENT_MED; + break; + } + + if (estimation_line_size == 0) + current_index = graph.layout.graph_max_size - + (graph.layout.graph_display_size_x * (int)(segment_duration / GRAPH_SEGMENT_HIGH)); + else + current_index = begining_session_index; + + current_index -= + (int)(current_page * (graph.layout.graph_display_size_x * (int)(segment_duration / GRAPH_SEGMENT_HIGH)) / + GRAPH_PAGE_SCROLL_SMOOTHNESS); + + if (current_index < 0) + current_index = 0; + + switch_zoom_profile(segment_duration); + + // x axis labels + renderText(label[0], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label1_x, graph.layout.label_y, 32, 32}); + renderText(label[1], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label2_x, graph.layout.label_y, 32, 32}); + renderText(label[2], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label3_x, graph.layout.label_y, 32, 32}); + renderText(label[3], font.small, COLOR_WHITE, &(SDL_Rect){graph.layout.label4_x, graph.layout.label_y, 32, 32}); + + // y axis "labels" + drawBatteryIcon(100, (SDL_Rect){graph.layout.icon_x, graph.layout.icon1_y}); + drawBatteryIcon(66, (SDL_Rect){graph.layout.icon_x, graph.layout.icon2_y}); + drawBatteryIcon(33, (SDL_Rect){graph.layout.icon_x, graph.layout.icon3_y}); + drawBatteryIcon(0, (SDL_Rect){graph.layout.icon_x, graph.layout.icon4_y}); + + char text_line[255]; + sprintf(text_line, "Since Charge: %s", session_duration); + renderText(text_line, font.medium, COLOR_WHITE, + &(SDL_Rect){graph.layout.label_session_x, graph.layout.label_session_y, graph.layout.label_size_x, + graph.layout.label_size_y}); + + sprintf(text_line, "Current: %s", current_percentage); + renderText(text_line, font.medium, COLOR_WHITE, + &(SDL_Rect){graph.layout.label_current_x, graph.layout.label_current_y, graph.layout.label_size_x, + graph.layout.label_size_y}); + + sprintf(text_line, "Remaining: %s", session_left); + renderTextAlignRight(text_line, font.medium, COLOR_WHITE, + &(SDL_Rect){graph.layout.label_left_x, graph.layout.label_left_y, graph.layout.label_size_x, + graph.layout.label_size_y}); + + sprintf(text_line, "Longest: %s", session_best); + renderTextAlignRight(text_line, font.medium, COLOR_WHITE, + &(SDL_Rect){graph.layout.label_best_x, graph.layout.label_best_y, graph.layout.label_size_x, + graph.layout.label_size_y}); + + int half_line_width = (int)(GRAPH_LINE_WIDTH) / 2; + + Uint32 white_pixel_color = RGB_GRAY; + Uint32 red_pixel_color = RGB_WHITE; + Uint32 blue_pixel_color = RGB_LIGHT_GRAY; + Uint32 pixel_color = white_pixel_color; + + // monochrome is more MinUI, but some colours are nice + const bool ilikeitcolourful = true; + if (ilikeitcolourful) { + white_pixel_color = SDL_MapRGB(screen->format, 255, 255, 255); + red_pixel_color = SDL_MapRGB(screen->format, 255, 170, 170); + blue_pixel_color = SDL_MapRGB(screen->format, 89, 167, 255); + pixel_color = white_pixel_color; + } + + int x; + int y; + int x_end = 0; + int y_end = 0; + + int zoom_level = (int)segment_duration / GRAPH_SEGMENT_HIGH; + + if (SDL_LockSurface(screen) == 0) { + // some constants to make it more readable + const int graph_display_right = graph.layout.graph_display_size_x + graph.layout.graph_display_start_x; + const int graph_display_bottom = graph.layout.graph_display_size_y + graph.layout.graph_display_start_y; + + for (int i = 0; i < graph.layout.graph_max_size - current_index; i += zoom_level) { + x = graph.layout.graph_display_start_x + (int)(i / zoom_level); + y = graph.graphic[i + current_index].pixel_height; + + bool is_charging = graph.graphic[i + current_index].is_charging; + bool is_estimated = graph.graphic[i + current_index].is_estimated; + // if ((!is_charging) + if ((!is_charging) && (!is_estimated)) + pixel_color = white_pixel_color; + else if (is_charging) + pixel_color = red_pixel_color; + else if (is_estimated) { + pixel_color = blue_pixel_color; + // magic numbers everywhere... + if (y < 5 && x < graph_display_right) { + x_end = x - 12; + y_end = graph_display_bottom - 45; + } + } + + if (x < graph_display_right && y > 0) { + // Actual graph line + if (half_line_width >= 0) { + for (int k = -half_line_width; k <= half_line_width; k++) { + int index = (graph_display_bottom - y + k) * screen->pitch + x * screen->format->BytesPerPixel; + *((Uint32 *)((Uint8 *)screen->pixels + index)) = pixel_color; + } + } + + // Area under the graph + if ((x % GRAPH_BACKGROUND_OPACITY) == 0) { + for (int k = y; k > 0; k--) { + if ((k % GRAPH_BACKGROUND_OPACITY) == 0) { + int index = (graph_display_bottom - k) * screen->pitch + x * screen->format->BytesPerPixel; + *((Uint32 *)((Uint8 *)screen->pixels + index)) = pixel_color; + } + } + } + } + } + SDL_UnlockSurface(screen); + if (x_end != 0) + GFX_blitAsset(ASSET_BATTERY_LOW, NULL, screen, &(SDL_Rect){x_end, y_end}); + } } void initLayout() { - // unscaled - int hw = screen->w; - int hh = screen->h; + // unscaled + int hw = screen->w; + int hh = screen->h; - // the title. just leave the default padding all around - graph.layout.sub_title_x = SCALE1(PADDING); - graph.layout.sub_title_y = SCALE1(PADDING); + // the title. just leave the default padding all around + graph.layout.sub_title_x = SCALE1(PADDING); + graph.layout.sub_title_y = SCALE1(PADDING); #define GRAPH_MARGIN 12 #define STATS_MARGIN 12 @@ -577,207 +552,197 @@ void initLayout() #define AXIS_WIDTH 16 #define STATS_HEIGHT 31 - // the diagram. - // x: start inside the default padding, and align with the text inside the pill above and below (BUTTON_MARGIN). - // y: default padding, below the title pill and some additional padding to leave some breathing room (BUTTON_MARGIN + GRAPH_MARGIN). - graph.layout.graph_display_start_x = SCALE1(PADDING + BUTTON_MARGIN); - graph.layout.graph_display_start_y = SCALE1(PADDING + PILL_SIZE + BUTTON_MARGIN + GRAPH_MARGIN); - - // x: stretch whole width inside default padding + extra margin (see above), leaving space top the right for icons. - // y: stretch whole height below graph_display_start_y, leaving room at the bottom for padding, button hints, stats, axis labels - graph.layout.graph_display_size_x = hw - SCALE1(PADDING * 2 + BUTTON_MARGIN * 2 + AXIS_MARGIN + AXIS_WIDTH); - graph.layout.graph_display_size_y = hh - SCALE1(PADDING * 2 + PILL_SIZE * 2 + BUTTON_MARGIN * 2 + GRAPH_MARGIN * 2 + STATS_MARGIN * 2 + STATS_HEIGHT); - - // y coord of x axis labels - graph.layout.label_y = graph.layout.graph_display_start_y + graph.layout.graph_display_size_y; - - // x axis: time - const int seglen = graph.layout.graph_display_size_x / GRAPH_SEGMENTS; - graph.layout.label1_x = graph.layout.graph_display_start_x + 2 * seglen - SCALE1(FONT_SMALL / 2); - graph.layout.label2_x = graph.layout.graph_display_start_x + 4 * seglen - SCALE1(FONT_SMALL / 2); - graph.layout.label3_x = graph.layout.graph_display_start_x + 6 * seglen - SCALE1(FONT_SMALL / 2); - graph.layout.label4_x = graph.layout.graph_display_start_x + 8 * seglen - SCALE1(FONT_SMALL / 2); - - // y axis: charge - graph.layout.icon_x = hw - SCALE1(PADDING + BUTTON_MARGIN + AXIS_WIDTH); - const int inc = graph.layout.graph_display_size_y / 4; - const int assetH = 10; - graph.layout.icon1_y = graph.layout.graph_display_start_y + inc / 2 - assetH / 2; - graph.layout.icon2_y = graph.layout.icon1_y + inc; - graph.layout.icon3_y = graph.layout.icon2_y + inc; - graph.layout.icon4_y = graph.layout.icon3_y + inc; - - graph.layout.label_current_x = SCALE1(PADDING + BUTTON_MARGIN); - graph.layout.label_current_y = graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN); - - graph.layout.label_session_x = SCALE1(PADDING + BUTTON_MARGIN); - graph.layout.label_session_y = graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN + BUTTON_MARGIN + FONT_MEDIUM); - - graph.layout.label_left_x = hw - SCALE1(PADDING + BUTTON_MARGIN + AXIS_WIDTH + AXIS_MARGIN); // right-aligned! - graph.layout.label_left_y = graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN); - - graph.layout.label_best_x = hw - SCALE1(PADDING + BUTTON_MARGIN + AXIS_WIDTH + AXIS_MARGIN); // right-aligned! - graph.layout.label_best_y = graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN + BUTTON_MARGIN + FONT_MEDIUM); - - graph.layout.label_size_x = graph.layout.graph_display_size_x / 2; - graph.layout.label_size_y = FONT_MEDIUM; // true for all? better make sure! - - graph.layout.graph_max_size = GRAPH_MAX_FULL_PAGES * graph.layout.graph_display_size_x; - - graph.graphic = (GraphSpot *)malloc(graph.layout.graph_max_size * sizeof(GraphSpot)); - for (int i = 0; i < graph.layout.graph_max_size; i++) - { - graph.graphic[i].pixel_height = 0; - graph.graphic[i].is_charging = false; - graph.graphic[i].is_estimated = false; - } + // the diagram. + // x: start inside the default padding, and align with the text inside the pill above and below (BUTTON_MARGIN). + // y: default padding, below the title pill and some additional padding to leave some breathing room (BUTTON_MARGIN + // + GRAPH_MARGIN). + graph.layout.graph_display_start_x = SCALE1(PADDING + BUTTON_MARGIN); + graph.layout.graph_display_start_y = SCALE1(PADDING + PILL_SIZE + BUTTON_MARGIN + GRAPH_MARGIN); + + // x: stretch whole width inside default padding + extra margin (see above), leaving space top the right for icons. + // y: stretch whole height below graph_display_start_y, leaving room at the bottom for padding, button hints, stats, + // axis labels + graph.layout.graph_display_size_x = hw - SCALE1(PADDING * 2 + BUTTON_MARGIN * 2 + AXIS_MARGIN + AXIS_WIDTH); + graph.layout.graph_display_size_y = hh - SCALE1(PADDING * 2 + PILL_SIZE * 2 + BUTTON_MARGIN * 2 + GRAPH_MARGIN * 2 + + STATS_MARGIN * 2 + STATS_HEIGHT); + + // y coord of x axis labels + graph.layout.label_y = graph.layout.graph_display_start_y + graph.layout.graph_display_size_y; + + // x axis: time + const int seglen = graph.layout.graph_display_size_x / GRAPH_SEGMENTS; + graph.layout.label1_x = graph.layout.graph_display_start_x + 2 * seglen - SCALE1(FONT_SMALL / 2); + graph.layout.label2_x = graph.layout.graph_display_start_x + 4 * seglen - SCALE1(FONT_SMALL / 2); + graph.layout.label3_x = graph.layout.graph_display_start_x + 6 * seglen - SCALE1(FONT_SMALL / 2); + graph.layout.label4_x = graph.layout.graph_display_start_x + 8 * seglen - SCALE1(FONT_SMALL / 2); + + // y axis: charge + graph.layout.icon_x = hw - SCALE1(PADDING + BUTTON_MARGIN + AXIS_WIDTH); + const int inc = graph.layout.graph_display_size_y / 4; + const int assetH = 10; + graph.layout.icon1_y = graph.layout.graph_display_start_y + inc / 2 - assetH / 2; + graph.layout.icon2_y = graph.layout.icon1_y + inc; + graph.layout.icon3_y = graph.layout.icon2_y + inc; + graph.layout.icon4_y = graph.layout.icon3_y + inc; + + graph.layout.label_current_x = SCALE1(PADDING + BUTTON_MARGIN); + graph.layout.label_current_y = graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN); + + graph.layout.label_session_x = SCALE1(PADDING + BUTTON_MARGIN); + graph.layout.label_session_y = + graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN + BUTTON_MARGIN + FONT_MEDIUM); + + graph.layout.label_left_x = hw - SCALE1(PADDING + BUTTON_MARGIN + AXIS_WIDTH + AXIS_MARGIN); // right-aligned! + graph.layout.label_left_y = graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN); + + graph.layout.label_best_x = hw - SCALE1(PADDING + BUTTON_MARGIN + AXIS_WIDTH + AXIS_MARGIN); // right-aligned! + graph.layout.label_best_y = + graph.layout.label_y + SCALE1(GRAPH_MARGIN + STATS_MARGIN + BUTTON_MARGIN + FONT_MEDIUM); + + graph.layout.label_size_x = graph.layout.graph_display_size_x / 2; + graph.layout.label_size_y = FONT_MEDIUM; // true for all? better make sure! + + graph.layout.graph_max_size = GRAPH_MAX_FULL_PAGES * graph.layout.graph_display_size_x; + + graph.graphic = (GraphSpot *)malloc(graph.layout.graph_max_size * sizeof(GraphSpot)); + for (int i = 0; i < graph.layout.graph_max_size; i++) { + graph.graphic[i].pixel_height = 0; + graph.graphic[i].is_charging = false; + graph.graphic[i].is_estimated = false; + } } int main(int argc, char *argv[]) { - InitSettings(); - - PWR_setCPUSpeed(CPU_SPEED_MENU); - device_model = PLAT_getModel(); - - screen = GFX_init(MODE_MAIN); - PAD_init(); - PWR_init(); - - signal(SIGINT, sigHandler); - signal(SIGTERM, sigHandler); - - initLayout(); - compute_graph(); - renderPage(); - - int dirty = 1; - int show_setting = 0; - int was_online = PLAT_isOnline(); - int had_bt = PLAT_btIsConnected(); - while (!quit) - { - uint32_t frame_start = SDL_GetTicks(); - - PAD_poll(); - - // This might be too harsh, but ignore all combos with MENU (most likely a shortcut for someone else) - if (PAD_justPressed(BTN_MENU)) - { - // ? - } - else - { - if (PAD_justRepeated(BTN_LEFT)) - { - dirty = 1; - int page_max = (int)(((GRAPH_MAX_FULL_PAGES) * (GRAPH_PAGE_SCROLL_SMOOTHNESS)) / (segment_duration / GRAPH_SEGMENT_HIGH)); - page_max -= GRAPH_PAGE_SCROLL_SMOOTHNESS; - - if (page_max > current_page) - current_page++; - } - else if (PAD_justRepeated(BTN_RIGHT)) - { - dirty = 1; - if (current_page > 0) - current_page--; - } - else if (PAD_justPressed(BTN_B)) - { - quit = 1; - } - else if (PAD_justPressed(BTN_L1) || PAD_justPressed(BTN_L2)) - { - if (current_zoom > 0) - { - current_page = 0; - current_zoom--; - dirty = 1; - } - } - else if (PAD_justPressed(BTN_R1) || PAD_justPressed(BTN_R2)) - { - if (current_zoom < 2) - { - current_page = 0; - current_zoom++; - dirty = 1; - } - } - } - - PWR_update(&dirty, &show_setting, NULL, NULL); - - int is_online = PLAT_isOnline(); - if (was_online != is_online) - dirty = 1; - was_online = is_online; - - int has_bt = PLAT_btIsConnected(); - if (had_bt != has_bt) - dirty = 1; - had_bt = has_bt; - - if (dirty) - { - GFX_clear(screen); - - // title pill - { - int ow = GFX_blitHardwareGroup(screen, show_setting); - int max_width = screen->w - SCALE1(PADDING * 2) - ow; - - char display_name[256]; - - switch (current_zoom) - { - case 0: - sprintf(display_name, "Battery usage: Last %s", "16 hours"); - break; - case 1: - sprintf(display_name, "Battery usage: Last %s", "8 hours"); - break; - case 2: - sprintf(display_name, "Battery usage: Last %s", "4 hours"); - break; - default: - sprintf(display_name, "Battery usage: Last %s", "8 hours"); - break; - } - - char title[256]; - int text_width = GFX_truncateText(font.large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); - max_width = MIN(max_width, text_width); - - SDL_Surface *text; - text = TTF_RenderUTF8_Blended(font.large, title, COLOR_WHITE); - - GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); - SDL_FreeSurface(text); - } - - renderPage(); - - if (show_setting) - GFX_blitHardwareHints(screen, show_setting); - else - GFX_blitButtonGroup((char *[]){"L/R", "SCROLL", "L1/R1", "ZOOM", NULL}, 0, screen, 0); - - GFX_blitButtonGroup((char *[]){"B", "BACK", NULL}, 1, screen, 1); - - GFX_flip(screen); - dirty = 0; - } - else - GFX_sync(); - } - - QuitSettings(); - PWR_quit(); - PAD_quit(); - GFX_quit(); - - return EXIT_SUCCESS; + InitSettings(); + + PWR_setCPUSpeed(CPU_SPEED_MENU); + device_model = PLAT_getModel(); + + screen = GFX_init(MODE_MAIN); + PAD_init(); + PWR_init(); + + signal(SIGINT, sigHandler); + signal(SIGTERM, sigHandler); + + initLayout(); + compute_graph(); + renderPage(); + + int dirty = 1; + int show_setting = 0; + int was_online = PLAT_isOnline(); + int had_bt = PLAT_btIsConnected(); + while (!quit) { + uint32_t frame_start = SDL_GetTicks(); + + PAD_poll(); + + // This might be too harsh, but ignore all combos with MENU (most likely a shortcut for someone else) + if (PAD_justPressed(BTN_MENU)) { + // ? + } else { + if (PAD_justRepeated(BTN_LEFT)) { + dirty = 1; + int page_max = (int)(((GRAPH_MAX_FULL_PAGES) * (GRAPH_PAGE_SCROLL_SMOOTHNESS)) / + (segment_duration / GRAPH_SEGMENT_HIGH)); + page_max -= GRAPH_PAGE_SCROLL_SMOOTHNESS; + + if (page_max > current_page) + current_page++; + } else if (PAD_justRepeated(BTN_RIGHT)) { + dirty = 1; + if (current_page > 0) + current_page--; + } else if (PAD_justPressed(BTN_B)) { + quit = 1; + } else if (PAD_justPressed(BTN_L1) || PAD_justPressed(BTN_L2)) { + if (current_zoom > 0) { + current_page = 0; + current_zoom--; + dirty = 1; + } + } else if (PAD_justPressed(BTN_R1) || PAD_justPressed(BTN_R2)) { + if (current_zoom < 2) { + current_page = 0; + current_zoom++; + dirty = 1; + } + } + } + + PWR_update(&dirty, &show_setting, NULL, NULL); + + int is_online = PLAT_isOnline(); + if (was_online != is_online) + dirty = 1; + was_online = is_online; + + int has_bt = PLAT_btIsConnected(); + if (had_bt != has_bt) + dirty = 1; + had_bt = has_bt; + + if (dirty) { + GFX_clear(screen); + + // title pill + { + int ow = GFX_blitHardwareGroup(screen, show_setting); + int max_width = screen->w - SCALE1(PADDING * 2) - ow; + + char display_name[256]; + + switch (current_zoom) { + case 0: + sprintf(display_name, "Battery usage: Last %s", "16 hours"); + break; + case 1: + sprintf(display_name, "Battery usage: Last %s", "8 hours"); + break; + case 2: + sprintf(display_name, "Battery usage: Last %s", "4 hours"); + break; + default: + sprintf(display_name, "Battery usage: Last %s", "8 hours"); + break; + } + + char title[256]; + int text_width = + GFX_truncateText(font.large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); + max_width = MIN(max_width, text_width); + + SDL_Surface *text; + text = TTF_RenderUTF8_Blended(font.large, title, COLOR_WHITE); + + GFX_blitPill(ASSET_BLACK_PILL, screen, + &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); + SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, + &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); + SDL_FreeSurface(text); + } + + renderPage(); + + if (show_setting) + GFX_blitHardwareHints(screen, show_setting); + else + GFX_blitButtonGroup((char *[]){"L/R", "SCROLL", "L1/R1", "ZOOM", NULL}, 0, screen, 0); + + GFX_blitButtonGroup((char *[]){"B", "BACK", NULL}, 1, screen, 1); + + GFX_flip(screen); + dirty = 0; + } else + GFX_sync(); + } + + QuitSettings(); + PWR_quit(); + PAD_quit(); + GFX_quit(); + + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/workspace/all/bootlogo/bootlogo.c b/workspace/all/bootlogo/bootlogo.c index c4cf58c2f..569b8d458 100644 --- a/workspace/all/bootlogo/bootlogo.c +++ b/workspace/all/bootlogo/bootlogo.c @@ -14,188 +14,171 @@ static bool quit = false; static void sigHandler(int sig) { - switch (sig) - { - case SIGINT: - case SIGTERM: - quit = true; - break; - default: - break; - } + switch (sig) { + case SIGINT: + case SIGTERM: + quit = true; + break; + default: + break; + } } static SDL_Surface *screen; -SDL_Surface** images; +SDL_Surface **images; char **image_paths; static int selected = 0; static int count = 0; int loadImages() { - char* device = getenv("DEVICE"); - // This needs to get a bit more flexible down the line, but for now we either expect the files - // in the pak root directory or in the "brick" subfolder. - char basepath[MAX_PATH]; - if(exactMatch("brick", device)) { - snprintf(basepath, sizeof(basepath), "%s/Bootlogo.pak/brick/", TOOLS_PATH); - } - else { - snprintf(basepath, sizeof(basepath), "%s/Bootlogo.pak/smartpro/", TOOLS_PATH); - } - - // grab all bmp files in the directory and load them with IMG_Load, - // keep them in an array of SDL_Surface pointers - DIR *dir; - struct dirent *ent; - if ((dir = opendir(basepath)) != NULL) { - while ((ent = readdir(dir)) != NULL) { - if (strstr(ent->d_name, ".bmp") != NULL) { - char path[MAX_PATH]; - snprintf(path, sizeof(path), "%s%s", basepath, ent->d_name); - SDL_Surface *bmp = IMG_Load(path); - if (bmp) { - count++; - images = realloc(images, sizeof(SDL_Surface*) * count); - images[count-1] = bmp; - image_paths = realloc(image_paths, sizeof(char*) * count); - image_paths[count-1] = strdup(path); - } - } - } - closedir(dir); - } else { - // could not open directory - LOG_error("could not open directory"); - if (CFG_getHaptics()) { - VIB_triplePulse(5, 150, 200); - } - return 0; - } - return count; + char *device = getenv("DEVICE"); + // This needs to get a bit more flexible down the line, but for now we either expect the files + // in the pak root directory or in the "brick" subfolder. + char basepath[MAX_PATH]; + if (exactMatch("brick", device)) { + snprintf(basepath, sizeof(basepath), "%s/Bootlogo.pak/brick/", TOOLS_PATH); + } else { + snprintf(basepath, sizeof(basepath), "%s/Bootlogo.pak/smartpro/", TOOLS_PATH); + } + + // grab all bmp files in the directory and load them with IMG_Load, + // keep them in an array of SDL_Surface pointers + DIR *dir; + struct dirent *ent; + if ((dir = opendir(basepath)) != NULL) { + while ((ent = readdir(dir)) != NULL) { + if (strstr(ent->d_name, ".bmp") != NULL) { + char path[MAX_PATH]; + snprintf(path, sizeof(path), "%s%s", basepath, ent->d_name); + SDL_Surface *bmp = IMG_Load(path); + if (bmp) { + count++; + images = realloc(images, sizeof(SDL_Surface *) * count); + images[count - 1] = bmp; + image_paths = realloc(image_paths, sizeof(char *) * count); + image_paths[count - 1] = strdup(path); + } + } + } + closedir(dir); + } else { + // could not open directory + LOG_error("could not open directory"); + if (CFG_getHaptics()) { + VIB_triplePulse(5, 150, 200); + } + return 0; + } + return count; } void unloadImages() { - for (int i = 0; i < count; i++) - { - SDL_FreeSurface(images[i]); - } - free(images); + for (int i = 0; i < count; i++) { + SDL_FreeSurface(images[i]); + } + free(images); } int main(int argc, char *argv[]) { - InitSettings(); - - PWR_setCPUSpeed(CPU_SPEED_MENU); - - screen = GFX_init(MODE_MAIN); - PAD_init(); - PWR_init(); - - signal(SIGINT, sigHandler); - signal(SIGTERM, sigHandler); - - loadImages(); - - int dirty = 1; - int show_setting = 0; - int was_online = PLAT_isOnline(); - int had_bt = PLAT_btIsConnected(); - while (!quit) - { - uint32_t frame_start = SDL_GetTicks(); - - PAD_poll(); - - // This might be too harsh, but ignore all combos with MENU (most likely a shortcut for someone else) - if (PAD_justPressed(BTN_MENU)) - { - // ? - } - else - { - if (PAD_justRepeated(BTN_LEFT)) - { - selected -= 1; - if (selected<0) - selected = count - 1; - dirty = 1; - } - else if (PAD_justRepeated(BTN_RIGHT)) - { - selected += 1; - if (selected>=count) - selected = 0; - dirty = 1; - } - else if (PAD_justPressed(BTN_A)) - { - // apply with system calls - // BOOT_PATH=/mnt/boot/ - // mkdir -p $BOOT_PATH - // mount -t vfat /dev/mmcblk0p1 $BOOT_PATH - // cp $LOGO_PATH $BOOT_PATH - // sync - // umount $BOOT_PATH - // reboot - char* boot_path = "/mnt/boot/"; - char* logo_path = image_paths[selected]; - char cmd[256]; - snprintf(cmd, sizeof(cmd), "mkdir -p %s && mount -t vfat /dev/mmcblk0p1 %s && cp \"%s\" %s/bootlogo.bmp && sync && umount %s && reboot", boot_path, boot_path, logo_path, boot_path, boot_path); - system(cmd); - } - else if (PAD_justPressed(BTN_B)) - { - quit = 1; - } - } - - PWR_update(&dirty, NULL, NULL, NULL); - - int is_online = PLAT_isOnline(); - if (was_online != is_online) - dirty = 1; - was_online = is_online; - - int has_bt = PLAT_btIsConnected(); - if (had_bt != has_bt) - dirty = 1; - had_bt = has_bt; - - if (dirty) - { - GFX_clear(screen); - - if(count > 0) { - // render the selected image, centered on screen - SDL_Surface *image = images[selected]; - SDL_Rect image_rect = { - screen->w /2 - image->w /2, - screen->h /2 - image->h / 2, - image->w, - image->h}; - SDL_BlitSurface(image, NULL, screen, &image_rect); - } - - GFX_blitButtonGroup((char *[]){"L/R", "SCROLL", NULL}, 0, screen, 0); - GFX_blitButtonGroup((char *[]){"A", "SET", "B", "BACK", NULL}, 1, screen, 1); - - GFX_flip(screen); - dirty = 0; - } - else - GFX_sync(); - } - - unloadImages(); - - QuitSettings(); - PWR_quit(); - PAD_quit(); - GFX_quit(); - - return EXIT_SUCCESS; + InitSettings(); + + PWR_setCPUSpeed(CPU_SPEED_MENU); + + screen = GFX_init(MODE_MAIN); + PAD_init(); + PWR_init(); + + signal(SIGINT, sigHandler); + signal(SIGTERM, sigHandler); + + loadImages(); + + int dirty = 1; + int show_setting = 0; + int was_online = PLAT_isOnline(); + int had_bt = PLAT_btIsConnected(); + while (!quit) { + uint32_t frame_start = SDL_GetTicks(); + + PAD_poll(); + + // This might be too harsh, but ignore all combos with MENU (most likely a shortcut for someone else) + if (PAD_justPressed(BTN_MENU)) { + // ? + } else { + if (PAD_justRepeated(BTN_LEFT)) { + selected -= 1; + if (selected < 0) + selected = count - 1; + dirty = 1; + } else if (PAD_justRepeated(BTN_RIGHT)) { + selected += 1; + if (selected >= count) + selected = 0; + dirty = 1; + } else if (PAD_justPressed(BTN_A)) { + // apply with system calls + // BOOT_PATH=/mnt/boot/ + // mkdir -p $BOOT_PATH + // mount -t vfat /dev/mmcblk0p1 $BOOT_PATH + // cp $LOGO_PATH $BOOT_PATH + // sync + // umount $BOOT_PATH + // reboot + char *boot_path = "/mnt/boot/"; + char *logo_path = image_paths[selected]; + char cmd[256]; + snprintf(cmd, sizeof(cmd), + "mkdir -p %s && mount -t vfat /dev/mmcblk0p1 %s && cp \"%s\" %s/bootlogo.bmp && sync && " + "umount %s && reboot", + boot_path, boot_path, logo_path, boot_path, boot_path); + system(cmd); + } else if (PAD_justPressed(BTN_B)) { + quit = 1; + } + } + + PWR_update(&dirty, NULL, NULL, NULL); + + int is_online = PLAT_isOnline(); + if (was_online != is_online) + dirty = 1; + was_online = is_online; + + int has_bt = PLAT_btIsConnected(); + if (had_bt != has_bt) + dirty = 1; + had_bt = has_bt; + + if (dirty) { + GFX_clear(screen); + + if (count > 0) { + // render the selected image, centered on screen + SDL_Surface *image = images[selected]; + SDL_Rect image_rect = {screen->w / 2 - image->w / 2, screen->h / 2 - image->h / 2, image->w, image->h}; + SDL_BlitSurface(image, NULL, screen, &image_rect); + } + + GFX_blitButtonGroup((char *[]){"L/R", "SCROLL", NULL}, 0, screen, 0); + GFX_blitButtonGroup((char *[]){"A", "SET", "B", "BACK", NULL}, 1, screen, 1); + + GFX_flip(screen); + dirty = 0; + } else + GFX_sync(); + } + + unloadImages(); + + QuitSettings(); + PWR_quit(); + PAD_quit(); + GFX_quit(); + + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/workspace/all/clock/clock.c b/workspace/all/clock/clock.c index 78f181a7a..b9f65dc48 100644 --- a/workspace/all/clock/clock.c +++ b/workspace/all/clock/clock.c @@ -19,21 +19,22 @@ enum { CURSOR_AMPM, }; -int main(int argc , char* argv[]) { +int main(int argc, char *argv[]) +{ PWR_setCPUSpeed(CPU_SPEED_MENU); - - SDL_Surface* screen = GFX_init(MODE_MAIN); + + SDL_Surface *screen = GFX_init(MODE_MAIN); PAD_init(); PWR_init(); InitSettings(); - + // TODO: make use of SCALE1() - SDL_Surface* digits = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(120,16), FIXED_DEPTH,RGBA_MASK_AUTO); + SDL_Surface *digits = SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(120, 16), FIXED_DEPTH, RGBA_MASK_AUTO); SDL_FillRect(digits, NULL, RGB_BLACK); - - SDL_Surface* digit; - char* chars[] = { "0","1","2","3","4","5","6","7","8","9","/",":", NULL }; - char* c; + + SDL_Surface *digit; + char *chars[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "/", ":", NULL}; + char *c; int i = 0; #define DIGIT_WIDTH 10 #define DIGIT_HEIGHT 16 @@ -42,23 +43,26 @@ int main(int argc , char* argv[]) { #define CHAR_COLON 11 while (c = chars[i]) { digit = TTF_RenderUTF8_Blended(font.large, c, COLOR_WHITE); - int y = i==CHAR_COLON ? SCALE1(-1.5) : 0; // : sits too low naturally + int y = i == CHAR_COLON ? SCALE1(-1.5) : 0; // : sits too low naturally // TODO: y offset is wrong here - // printf("%s x:%i y:%i SCALE1(DIGIT_HEIGHT):%i SCALE1(DIGIT_HEIGHT) - digit->h:%i\n", c, (i * SCALE1(DIGIT_WIDTH)), y, SCALE1(DIGIT_HEIGHT), SCALE1(DIGIT_HEIGHT) - digit->h); fflush(stdout); - SDL_BlitSurface(digit, NULL, digits, &(SDL_Rect){ (i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w)/2, y + (SCALE1(DIGIT_HEIGHT) - digit->h)/2 }); + // printf("%s x:%i y:%i SCALE1(DIGIT_HEIGHT):%i SCALE1(DIGIT_HEIGHT) - digit->h:%i\n", c, (i * + // SCALE1(DIGIT_WIDTH)), y, SCALE1(DIGIT_HEIGHT), SCALE1(DIGIT_HEIGHT) - digit->h); fflush(stdout); + SDL_BlitSurface(digit, NULL, digits, + &(SDL_Rect){(i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w) / 2, + y + (SCALE1(DIGIT_HEIGHT) - digit->h) / 2}); SDL_FreeSurface(digit); i += 1; } - + SDL_Event event; int quit = 0; int save_changes = 0; int select_cursor = 0; int show_24hour = exists(USERDATA_PATH "/show_24hour"); - + time_t t = time(NULL); struct tm tm = *localtime(&t); - + int32_t day_selected = tm.tm_mday; int32_t month_selected = tm.tm_mon + 1; uint32_t year_selected = tm.tm_year + 1900; @@ -66,264 +70,285 @@ int main(int argc , char* argv[]) { int32_t minute_selected = tm.tm_min; int32_t seconds_selected = tm.tm_sec; int32_t am_selected = tm.tm_hour < 12; - + // x,y,w are pre-scaled - int blit(int i, int x, int y) { - SDL_BlitSurface(digits, &(SDL_Rect){i*SCALE1(10),0,SCALE2(10,16)}, screen, &(SDL_Rect){x,y}); + int blit(int i, int x, int y) + { + SDL_BlitSurface(digits, &(SDL_Rect){i * SCALE1(10), 0, SCALE2(10, 16)}, screen, &(SDL_Rect){x, y}); return x + SCALE1(10); } - void blitBar(int x, int y, int w) { - GFX_blitPill(ASSET_UNDERLINE, screen, &(SDL_Rect){x,y,w}); + void blitBar(int x, int y, int w) + { + GFX_blitPill(ASSET_UNDERLINE, screen, &(SDL_Rect){x, y, w}); } - int blitNumber(int num, int x, int y) { + int blitNumber(int num, int x, int y) + { int n; if (num > 999) { n = num / 1000; num -= n * 1000; - x = blit(n, x,y); - + x = blit(n, x, y); + n = num / 100; num -= n * 100; - x = blit(n, x,y); + x = blit(n, x, y); } n = num / 10; num -= n * 10; - x = blit(n, x,y); - + x = blit(n, x, y); + n = num; - x = blit(n, x,y); - + x = blit(n, x, y); + return x; } - void validate(void) { + void validate(void) + { // leap year uint32_t february_days = 28; - if ( ((year_selected % 4 == 0) && (year_selected % 100 != 0)) || (year_selected % 400 == 0)) february_days = 29; - + if (((year_selected % 4 == 0) && (year_selected % 100 != 0)) || (year_selected % 400 == 0)) + february_days = 29; + // day // if (day_selected < 1) day_selected = 1; - if (month_selected > 12) month_selected -= 12; - else if (month_selected < 1) month_selected += 12; - - if (year_selected > 2100) year_selected = 2100; - else if (year_selected < 1970) year_selected = 1970; - - switch(month_selected) - { - case 2: - if (day_selected > february_days) day_selected -= february_days; - else if (day_selected<1) day_selected += february_days; - break; - case 4: - case 6: - case 9: - case 11: - if (day_selected > 30) day_selected -= 30; - else if (day_selected < 1) day_selected += 30; + if (month_selected > 12) + month_selected -= 12; + else if (month_selected < 1) + month_selected += 12; - break; - default: - if (day_selected > 31) day_selected -= 31; - else if (day_selected < 1) day_selected += 31; - break; + if (year_selected > 2100) + year_selected = 2100; + else if (year_selected < 1970) + year_selected = 1970; + + switch (month_selected) { + case 2: + if (day_selected > february_days) + day_selected -= february_days; + else if (day_selected < 1) + day_selected += february_days; + break; + case 4: + case 6: + case 9: + case 11: + if (day_selected > 30) + day_selected -= 30; + else if (day_selected < 1) + day_selected += 30; + + break; + default: + if (day_selected > 31) + day_selected -= 31; + else if (day_selected < 1) + day_selected += 31; + break; } - + // time - if (hour_selected > 23) hour_selected -= 24; - else if (hour_selected < 0) hour_selected += 24; - if (minute_selected > 59) minute_selected -= 60; - else if (minute_selected < 0) minute_selected += 60; - if (seconds_selected > 59) seconds_selected -= 60; - else if (seconds_selected < 0) seconds_selected += 60; + if (hour_selected > 23) + hour_selected -= 24; + else if (hour_selected < 0) + hour_selected += 24; + if (minute_selected > 59) + minute_selected -= 60; + else if (minute_selected < 0) + minute_selected += 60; + if (seconds_selected > 59) + seconds_selected -= 60; + else if (seconds_selected < 0) + seconds_selected += 60; } - + int option_count = 7; int dirty = 1; int show_setting = 0; int was_online = PLAT_isOnline(); - int had_bt = PLAT_btIsConnected(); - while(!quit) { + int had_bt = PLAT_btIsConnected(); + while (!quit) { uint32_t frame_start = SDL_GetTicks(); - + PAD_poll(); - + if (PAD_justRepeated(BTN_UP)) { dirty = 1; - switch(select_cursor) { - case CURSOR_YEAR: - year_selected++; + switch (select_cursor) { + case CURSOR_YEAR: + year_selected++; break; - case CURSOR_MONTH: - month_selected++; + case CURSOR_MONTH: + month_selected++; break; - case CURSOR_DAY: - day_selected++; + case CURSOR_DAY: + day_selected++; break; - case CURSOR_HOUR: - hour_selected++; + case CURSOR_HOUR: + hour_selected++; break; - case CURSOR_MINUTE: - minute_selected++; + case CURSOR_MINUTE: + minute_selected++; break; - case CURSOR_SECOND: - seconds_selected++; + case CURSOR_SECOND: + seconds_selected++; break; - case CURSOR_AMPM: - hour_selected += 12; + case CURSOR_AMPM: + hour_selected += 12; break; - default: + default: break; } - } - else if (PAD_justRepeated(BTN_DOWN)) { + } else if (PAD_justRepeated(BTN_DOWN)) { dirty = 1; - switch(select_cursor) { - case CURSOR_YEAR: - year_selected--; + switch (select_cursor) { + case CURSOR_YEAR: + year_selected--; break; - case CURSOR_MONTH: - month_selected--; + case CURSOR_MONTH: + month_selected--; break; - case CURSOR_DAY: - day_selected--; + case CURSOR_DAY: + day_selected--; break; - case CURSOR_HOUR: - hour_selected--; + case CURSOR_HOUR: + hour_selected--; break; - case CURSOR_MINUTE: - minute_selected--; + case CURSOR_MINUTE: + minute_selected--; break; - case CURSOR_SECOND: - seconds_selected--; + case CURSOR_SECOND: + seconds_selected--; break; - case CURSOR_AMPM: - hour_selected -= 12; + case CURSOR_AMPM: + hour_selected -= 12; break; - default: + default: break; } - } - else if (PAD_justRepeated(BTN_LEFT)) { + } else if (PAD_justRepeated(BTN_LEFT)) { dirty = 1; select_cursor--; - if (select_cursor < 0) select_cursor += option_count; - } - else if (PAD_justRepeated(BTN_RIGHT)) { + if (select_cursor < 0) + select_cursor += option_count; + } else if (PAD_justRepeated(BTN_RIGHT)) { dirty = 1; select_cursor++; - if (select_cursor >= option_count) select_cursor -= option_count; - } - else if (PAD_justPressed(BTN_A)) { + if (select_cursor >= option_count) + select_cursor -= option_count; + } else if (PAD_justPressed(BTN_A)) { save_changes = 1; quit = 1; - } - else if (PAD_justPressed(BTN_B)) { + } else if (PAD_justPressed(BTN_B)) { quit = 1; - } - else if (PAD_justPressed(BTN_SELECT)) { + } else if (PAD_justPressed(BTN_SELECT)) { dirty = 1; show_24hour = !show_24hour; option_count = (show_24hour ? CURSOR_SECOND : CURSOR_AMPM) + 1; - if (select_cursor >= option_count) select_cursor -= option_count; - + if (select_cursor >= option_count) + select_cursor -= option_count; + if (show_24hour) { system("touch " USERDATA_PATH "/show_24hour"); - } - else { + } else { system("rm " USERDATA_PATH "/show_24hour"); } } - - PWR_update(&dirty, NULL, NULL,NULL); - + + PWR_update(&dirty, NULL, NULL, NULL); + int is_online = PLAT_isOnline(); - if (was_online!=is_online) + if (was_online != is_online) dirty = 1; was_online = is_online; - int has_bt = PLAT_btIsConnected(); - if (had_bt != has_bt) - dirty = 1; - had_bt = has_bt; - + int has_bt = PLAT_btIsConnected(); + if (had_bt != has_bt) + dirty = 1; + had_bt = has_bt; + if (dirty) { validate(); GFX_clear(screen); - + GFX_blitHardwareGroup(screen, show_setting); - - if (show_setting) GFX_blitHardwareHints(screen, show_setting); - else GFX_blitButtonGroup((char*[]){ "SELECT",show_24hour?"12 HOUR":"24 HOUR", NULL }, 0, screen, 0); - GFX_blitButtonGroup((char*[]){ "B","CANCEL", "A","SET", NULL }, 1, screen, 1); - + if (show_setting) + GFX_blitHardwareHints(screen, show_setting); + else + GFX_blitButtonGroup((char *[]){"SELECT", show_24hour ? "12 HOUR" : "24 HOUR", NULL}, 0, screen, 0); + + GFX_blitButtonGroup((char *[]){"B", "CANCEL", "A", "SET", NULL}, 1, screen, 1); + // 376 or 446 (@2x) // 188 or 223 (@1x) - int ox = (screen->w - (show_24hour?SCALE1(188):SCALE1(223))) / 2; - + int ox = (screen->w - (show_24hour ? SCALE1(188) : SCALE1(223))) / 2; + // datetime int x = ox; - int y = SCALE1((((FIXED_HEIGHT / FIXED_SCALE)-PILL_SIZE-DIGIT_HEIGHT)/2)); - - x = blitNumber(year_selected, x,y); - x = blit(CHAR_SLASH, x,y); - x = blitNumber(month_selected, x,y); - x = blit(CHAR_SLASH, x,y); - x = blitNumber(day_selected, x,y); + int y = SCALE1((((FIXED_HEIGHT / FIXED_SCALE) - PILL_SIZE - DIGIT_HEIGHT) / 2)); + + x = blitNumber(year_selected, x, y); + x = blit(CHAR_SLASH, x, y); + x = blitNumber(month_selected, x, y); + x = blit(CHAR_SLASH, x, y); + x = blitNumber(day_selected, x, y); x += SCALE1(10); // space - + am_selected = hour_selected < 12; if (show_24hour) { - x = blitNumber(hour_selected, x,y); - } - else { + x = blitNumber(hour_selected, x, y); + } else { // if (select_cursor==CURSOR_HOUR) blitNumber(hour_selected, x,233); - + // 12 hour int hour = hour_selected; - if (hour==0) hour = 12; - else if (hour>12) hour -= 12; - x = blitNumber(hour, x,y); + if (hour == 0) + hour = 12; + else if (hour > 12) + hour -= 12; + x = blitNumber(hour, x, y); } - x = blit(CHAR_COLON, x,y); - x = blitNumber(minute_selected, x,y); - x = blit(CHAR_COLON, x,y); - x = blitNumber(seconds_selected, x,y); - + x = blit(CHAR_COLON, x, y); + x = blitNumber(minute_selected, x, y); + x = blit(CHAR_COLON, x, y); + x = blitNumber(seconds_selected, x, y); + int ampm_w; if (!show_24hour) { x += SCALE1(10); // space - SDL_Surface* text = TTF_RenderUTF8_Blended(font.large, am_selected ? "AM" : "PM", COLOR_WHITE); + SDL_Surface *text = TTF_RenderUTF8_Blended(font.large, am_selected ? "AM" : "PM", COLOR_WHITE); ampm_w = text->w + SCALE1(2); - SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){x,y-SCALE1(3)}); + SDL_BlitSurface(text, NULL, screen, &(SDL_Rect){x, y - SCALE1(3)}); SDL_FreeSurface(text); } - + // cursor x = ox; y += SCALE1(19); - if (select_cursor!=CURSOR_YEAR) { + if (select_cursor != CURSOR_YEAR) { x += SCALE1(50); // YYYY/ x += (select_cursor - 1) * SCALE1(30); } - blitBar(x,y, (select_cursor==CURSOR_YEAR ? SCALE1(40) : (select_cursor==CURSOR_AMPM ? ampm_w : SCALE1(20)))); - + blitBar(x, y, + (select_cursor == CURSOR_YEAR ? SCALE1(40) : (select_cursor == CURSOR_AMPM ? ampm_w : SCALE1(20)))); + GFX_flip(screen); dirty = 0; - } - else GFX_sync(); + } else + GFX_sync(); } - + SDL_FreeSurface(digits); - + QuitSettings(); PWR_quit(); PAD_quit(); GFX_quit(); - - if (save_changes) PLAT_setDateTime(year_selected, month_selected, day_selected, hour_selected, minute_selected, seconds_selected); - + + if (save_changes) + PLAT_setDateTime(year_selected, month_selected, day_selected, hour_selected, minute_selected, seconds_selected); + return EXIT_SUCCESS; } diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 8cd7c3822..ef6865900 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -30,8 +30,7 @@ void LOG_note(int level, const char *fmt, ...) va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - switch (level) - { + switch (level) { #ifdef DEBUG case LOG_DEBUG: printf("[DEBUG] %s", buf); @@ -82,8 +81,7 @@ enum LightProfile profile_override[PROFILE_OVERRIDE_SIZE]; volatile int useAutoCpu; -static struct GFX_Context -{ +static struct GFX_Context { SDL_Surface *screen; SDL_Surface *assets; @@ -155,13 +153,8 @@ static inline uint32_t UintMult(uint32_t color, uint32_t modulate_rgb) } /////////////////////////////// -static int qualityLevels[] = { - 3, - 4, - 2, - 1}; -static struct PWR_Context -{ +static int qualityLevels[] = {3, 4, 2, 1}; +static struct PWR_Context { int initialized; int can_sleep; @@ -182,8 +175,7 @@ static struct PWR_Context SDL_Surface *overlay; } pwr = {0}; -static struct SND_Context -{ +static struct SND_Context { int initialized; double frame_rate; @@ -283,7 +275,7 @@ SDL_Surface *GFX_init(int mode) gfx.screen = PLAT_initVideo(); gfx.vsync = VSYNC_STRICT; gfx.mode = mode; - + CFG_init(GFX_loadSystemFont, GFX_updateColors); // TODO: this doesn't really belong here... @@ -367,7 +359,6 @@ SDL_Surface *GFX_init(int mode) } void GFX_quit(void) { - TTF_CloseFont(font.large); TTF_CloseFont(font.medium); TTF_CloseFont(font.small); @@ -425,36 +416,28 @@ void GFX_startFrame(void) void chmodfile(const char *file, int writable) { struct stat statbuf; - if (stat(file, &statbuf) == 0) - { + if (stat(file, &statbuf) == 0) { mode_t newMode; - if (writable) - { + if (writable) { // Add write permissions for all users newMode = statbuf.st_mode | S_IWUSR | S_IWGRP | S_IWOTH; - } - else - { + } else { // Remove write permissions for all users newMode = statbuf.st_mode & ~(S_IWUSR | S_IWGRP | S_IWOTH); } // Apply the new permissions - if (chmod(file, newMode) != 0) - { + if (chmod(file, newMode) != 0) { printf("chmod error %d %s", writable, file); } - } - else - { + } else { printf("stat error %d %s", writable, file); } } uint32_t GFX_extract_average_color(const void *data, unsigned width, unsigned height, size_t pitch) { - if (!data) - { + if (!data) { return 0; } @@ -466,10 +449,8 @@ uint32_t GFX_extract_average_color(const void *data, unsigned width, unsigned he uint64_t total_b = 0; uint32_t colorful_pixel_count = 0; - for (unsigned y = 0; y < height; y++) - { - for (unsigned x = 0; x < width; x++) - { + for (unsigned y = 0; y < height; y++) { + for (unsigned x = 0; x < width; x++) { uint16_t pixel = pixels[y * (pitch / 2) + x]; uint8_t r = ((pixel & 0xF800) >> 11) << 3; @@ -484,8 +465,7 @@ uint32_t GFX_extract_average_color(const void *data, unsigned width, unsigned he uint8_t min_c = fminf(fminf(r, g), b); uint8_t saturation = max_c == 0 ? 0 : (max_c - min_c) * 255 / max_c; - if (saturation > 50 && max_c > 50) - { + if (saturation > 50 && max_c > 50) { total_r += r; total_g += g; total_b += b; @@ -494,15 +474,11 @@ uint32_t GFX_extract_average_color(const void *data, unsigned width, unsigned he } } - if (colorful_pixel_count == 0) - { - + if (colorful_pixel_count == 0) { colorful_pixel_count = pixel_count; total_r = total_g = total_b = 0; - for (unsigned y = 0; y < height; y++) - { - for (unsigned x = 0; x < width; x++) - { + for (unsigned y = 0; y < height; y++) { + for (unsigned x = 0; x < width; x++) { uint16_t pixel = pixels[y * (pitch / 2) + x]; uint8_t r = ((pixel & 0xF800) >> 11) << 3; uint8_t g = ((pixel & 0x07E0) >> 5) << 2; @@ -533,14 +509,12 @@ void GFX_setAmbientColor(const void *data, unsigned width, unsigned height, size uint32_t dominant_color = GFX_extract_average_color(data, width, height, pitch); - if (mode == 1 || mode == 2 || mode == 5) - { + if (mode == 1 || mode == 2 || mode == 5) { (lightsAmbient)[2].color1 = dominant_color; (lightsAmbient)[2].effect = 4; (lightsAmbient)[2].brightness = 100; } - if (mode == 1 || mode == 3) - { + if (mode == 1 || mode == 3) { (lightsAmbient)[0].color1 = dominant_color; (lightsAmbient)[0].effect = 4; (lightsAmbient)[0].brightness = 100; @@ -548,8 +522,7 @@ void GFX_setAmbientColor(const void *data, unsigned width, unsigned height, size (lightsAmbient)[1].effect = 4; (lightsAmbient)[1].brightness = 100; } - if (mode == 1 || mode == 4 || mode == 5) - { + if (mode == 1 || mode == 4 || mode == 5) { (lightsAmbient)[3].color1 = dominant_color; (lightsAmbient)[3].effect = 4; (lightsAmbient)[3].brightness = 100; @@ -558,7 +531,6 @@ void GFX_setAmbientColor(const void *data, unsigned width, unsigned height, size void GFX_flip(SDL_Surface *screen) { - PLAT_flip(screen, 0); currentfps = current_fps; @@ -576,12 +548,10 @@ void GFX_flip(SDL_Surface *screen) fps_buffer_index = (fps_buffer_index + 1) % FPS_BUFFER_SIZE; // give it a little bit to stabilize and then use, meanwhile the buffer will // cover it - if (fps_counter > 100) - { + if (fps_counter > 100) { double average_fps = 0.0; int fpsbuffersize = MIN(fps_counter, FPS_BUFFER_SIZE); - for (int i = 0; i < fpsbuffersize; i++) - { + for (int i = 0; i < fpsbuffersize; i++) { average_fps += fps_buffer[i]; } average_fps /= fpsbuffersize; @@ -592,7 +562,6 @@ void GFX_flip(SDL_Surface *screen) } void GFX_GL_Swap() { - PLAT_GL_Swap(); currentfps = current_fps; @@ -610,12 +579,10 @@ void GFX_GL_Swap() fps_buffer_index = (fps_buffer_index + 1) % FPS_BUFFER_SIZE; // give it a little bit to stabilize and then use, meanwhile the buffer will // cover it - if (fps_counter > 100) - { + if (fps_counter > 100) { double average_fps = 0.0; int fpsbuffersize = MIN(fps_counter, FPS_BUFFER_SIZE); - for (int i = 0; i < fpsbuffersize; i++) - { + for (int i = 0; i < fpsbuffersize; i++) { average_fps += fps_buffer[i]; } average_fps /= fpsbuffersize; @@ -628,16 +595,13 @@ void GFX_GL_Swap() void GFX_sync(void) { uint32_t frame_duration = SDL_GetTicks() - frame_start; - if (gfx.vsync != VSYNC_OFF) - { + if (gfx.vsync != VSYNC_OFF) { // this limiting condition helps SuperFX chip games - if (gfx.vsync == VSYNC_STRICT || frame_start == 0 || frame_duration < FRAME_BUDGET) - { // only wait if we're under frame budget + if (gfx.vsync == VSYNC_STRICT || frame_start == 0 || + frame_duration < FRAME_BUDGET) { // only wait if we're under frame budget PLAT_vsync(FRAME_BUDGET - frame_duration); } - } - else - { + } else { if (frame_duration < FRAME_BUDGET) SDL_Delay(FRAME_BUDGET - frame_duration); } @@ -656,8 +620,7 @@ void GFX_flip_fixed_rate(SDL_Surface *screen, double target_fps) int64_t perf_freq = SDL_GetPerformanceFrequency(); int64_t now = SDL_GetPerformanceCounter(); - if (++frame_index == 0 || target_fps != last_target_fps) - { + if (++frame_index == 0 || target_fps != last_target_fps) { frame_index = 0; first_frame_start_time = now; last_target_fps = target_fps; @@ -675,38 +638,31 @@ void GFX_flip_fixed_rate(SDL_Surface *screen, double target_fps) // time_of_frame, // now - time_of_frame); - if (offset > 0) - { - if (offset > max_lost_frames * frame_duration) - { + if (offset > 0) { + if (offset > max_lost_frames * frame_duration) { frame_index = -1; last_target_fps = 0.0; - LOG_debug("%s: lost sync by more than %d frames (late) @%llu -> reset\n\n", __FUNCTION__, max_lost_frames, SDL_GetPerformanceCounter()); + LOG_debug("%s: lost sync by more than %d frames (late) @%llu -> reset\n\n", __FUNCTION__, max_lost_frames, + SDL_GetPerformanceCounter()); } - } - else - { - if (offset < -max_lost_frames * frame_duration) - { + } else { + if (offset < -max_lost_frames * frame_duration) { frame_index = -1; last_target_fps = 0.0; - LOG_debug("%s: lost sync by more than %d frames (early ?!) @%llu -> reset\n\n", __FUNCTION__, max_lost_frames, SDL_GetPerformanceCounter()); - } - else if (offset < 0) - { + LOG_debug("%s: lost sync by more than %d frames (early ?!) @%llu -> reset\n\n", __FUNCTION__, + max_lost_frames, SDL_GetPerformanceCounter()); + } else if (offset < 0) { useconds_t time_to_sleep_us = (useconds_t)((time_of_frame - now) * 1e6 / perf_freq); // The OS scheduling algorithm cannot guarantee that // the sleep will last the exact amount of requested time. // We sleep as much as we can using the OS primitive. const useconds_t min_waiting_time = 2000; - if (time_to_sleep_us > min_waiting_time) - { + if (time_to_sleep_us > min_waiting_time) { usleep(time_to_sleep_us - min_waiting_time); } - while (SDL_GetPerformanceCounter() < time_of_frame) - { + while (SDL_GetPerformanceCounter() < time_of_frame) { // nothing... } } @@ -721,19 +677,15 @@ void GFX_flip_fixed_rate(SDL_Surface *screen, double target_fps) fps_buffer_index = (fps_buffer_index + 1) % FPS_BUFFER_SIZE; // give it a little bit to stabilize and then use, meanwhile the buffer will // cover it - if (fps_counter++ > 100) - { + if (fps_counter++ > 100) { double average_fps = 0.0; int fpsbuffersize = MIN(fps_counter, FPS_BUFFER_SIZE); - for (int i = 0; i < fpsbuffersize; i++) - { + for (int i = 0; i < fpsbuffersize; i++) { average_fps += fps_buffer[i]; } average_fps /= fpsbuffersize; currentfps = current_fps = average_fps; - } - else - { + } else { currentfps = current_fps = target_fps; } per_frame_start = SDL_GetPerformanceCounter(); @@ -747,8 +699,13 @@ void GFX_delay(void) SDL_Delay(((1 / SCREEN_FPS) * 1000) - frame_duration); } -FALLBACK_IMPLEMENTATION int PLAT_supportsOverscan(void) { return 0; } -FALLBACK_IMPLEMENTATION void PLAT_setEffectColor(int next_color) {} +FALLBACK_IMPLEMENTATION int PLAT_supportsOverscan(void) +{ + return 0; +} +FALLBACK_IMPLEMENTATION void PLAT_setEffectColor(int next_color) +{ +} int GFX_truncateText(TTF_Font *font, const char *in_name, char *out_name, int max_width, int padding) { @@ -757,8 +714,7 @@ int GFX_truncateText(TTF_Font *font, const char *in_name, char *out_name, int ma TTF_SizeUTF8(font, out_name, &text_width, NULL); text_width += padding; - while (text_width > max_width) - { + while (text_width > max_width) { int len = strlen(out_name); strcpy(&out_name[len - 4], "...\0"); TTF_SizeUTF8(font, out_name, &text_width, NULL); @@ -797,8 +753,7 @@ int GFX_wrapText(TTF_Font *font, char *str, int max_width, int max_lines) char buffer[MAX_PATH]; TTF_SizeUTF8(font, line, &line_width, NULL); - if (line_width <= max_width) - { + if (line_width <= max_width) { line_width = GFX_truncateText(font, line, buffer, max_width, 0); strcpy(line, buffer); return line_width; @@ -808,16 +763,12 @@ int GFX_wrapText(TTF_Font *font, char *str, int max_width, int max_lines) char *tmp = line; int lines = 1; int i = 0; - while (!max_lines || lines < max_lines) - { + while (!max_lines || lines < max_lines) { tmp = strchr(tmp, ' '); - if (!tmp) - { - if (prev) - { + if (!tmp) { + if (prev) { TTF_SizeUTF8(font, line, &line_width, NULL); - if (line_width >= max_width) - { + if (line_width >= max_width) { if (line_width > max_line_width) max_line_width = line_width; prev[0] = '\n'; @@ -830,8 +781,7 @@ int GFX_wrapText(TTF_Font *font, char *str, int max_width, int max_lines) TTF_SizeUTF8(font, line, &line_width, NULL); - if (line_width >= max_width) - { // wrap + if (line_width >= max_width) { // wrap if (line_width > max_line_width) max_line_width = line_width; tmp[0] = ' '; @@ -840,9 +790,7 @@ int GFX_wrapText(TTF_Font *font, char *str, int max_width, int max_lines) prev += 1; line = prev; lines += 1; - } - else - { // continue + } else { // continue tmp[0] = ' '; prev = tmp; tmp += 1; @@ -862,8 +810,7 @@ int GFX_wrapText(TTF_Font *font, char *str, int max_width, int max_lines) // scale_blend (and supporting logic) from picoarch -struct blend_args -{ +struct blend_args { int w_ratio_in; int w_ratio_out; uint16_t w_bp[2]; @@ -904,32 +851,30 @@ static inline uint32x4_t average32_neon(uint32x4_t a, uint32x4_t b) static inline uint32_t average16(uint32_t c1, uint32_t c2) { uint32_t ret, lowbits = 0x0821; - asm volatile( - "eor %0, %2, %3\n\t" - "and %0, %0, %1\n\t" - "add %0, %3, %0\n\t" - "add %0, %0, %2\n\t" - "lsr %0, %0, #1\n\t" - : "=&r"(ret) - : "r"(lowbits), "r"(c1), "r"(c2)); + asm volatile("eor %0, %2, %3\n\t" + "and %0, %0, %1\n\t" + "add %0, %3, %0\n\t" + "add %0, %0, %2\n\t" + "lsr %0, %0, #1\n\t" + : "=&r"(ret) + : "r"(lowbits), "r"(c1), "r"(c2)); return ret; } static inline uint32_t average32(uint32_t c1, uint32_t c2) { uint32_t ret, lowbits = 0x08210821; - asm volatile( - "eor %0, %3, %1\n\t" - "and %0, %0, %2\n\t" - "adds %0, %1, %0\n\t" - "and %1, %1, #0\n\t" - "movcs %1, #0x80000000\n\t" - "adds %0, %0, %3\n\t" - "rrx %0, %0\n\t" - "orr %0, %0, %1\n\t" - : "=&r"(ret), "+r"(c2) - : "r"(lowbits), "r"(c1) - : "cc"); + asm volatile("eor %0, %3, %1\n\t" + "and %0, %0, %2\n\t" + "adds %0, %1, %0\n\t" + "and %1, %1, #0\n\t" + "movcs %1, #0x80000000\n\t" + "adds %0, %0, %3\n\t" + "rrx %0, %0\n\t" + "orr %0, %0, %1\n\t" + : "=&r"(ret), "+r"(c2) + : "r"(lowbits), "r"(c1) + : "cc"); return ret; } @@ -939,30 +884,28 @@ static inline uint32_t average32(uint32_t c1, uint32_t c2) static inline uint32_t average16(uint32_t c1, uint32_t c2) { uint32_t result; - asm volatile( - "and w2, %w0, %w1\n\t" - "eor w3, %w0, %w1\n\t" - "lsr w3, w3, #1\n\t" - "add %w2, w2, w3\n\t" - "mov %w0, w2\n\t" - : "+r"(c1) - : "r"(c2) - : "w2", "w3"); + asm volatile("and w2, %w0, %w1\n\t" + "eor w3, %w0, %w1\n\t" + "lsr w3, w3, #1\n\t" + "add %w2, w2, w3\n\t" + "mov %w0, w2\n\t" + : "+r"(c1) + : "r"(c2) + : "w2", "w3"); return c1; } static inline uint32_t average32(uint32_t c1, uint32_t c2) { uint32_t result; - asm volatile( - "and w2, %w0, %w1\n\t" - "eor w3, %w0, %w1\n\t" - "lsr w3, w3, #1\n\t" - "add w2, w2, w3\n\t" - "mov %w0, w2\n\t" - : "+r"(c1) - : "r"(c2) - : "w2", "w3"); + asm volatile("and w2, %w0, %w1\n\t" + "eor w3, %w0, %w1\n\t" + "lsr w3, w3, #1\n\t" + "add w2, w2, w3\n\t" + "mov %w0, w2\n\t" + : "+r"(c1) + : "r"(c2) + : "w2", "w3"); return c1; } @@ -986,7 +929,8 @@ static inline int gcd(int a, int b) return b ? gcd(b, a % b) : a; } -static void scaleAA(void *__restrict src, void *__restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_w, uint32_t dst_h, uint32_t dst_p) +static void scaleAA(void *__restrict src, void *__restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_w, + uint32_t dst_h, uint32_t dst_p) { int dy = 0; int lines = h; @@ -999,10 +943,8 @@ static void scaleAA(void *__restrict src, void *__restrict dst, uint32_t w, uint int rat_dst_h = blend_args.h_ratio_out; uint16_t *bh = blend_args.h_bp; - while (lines--) - { - while (dy < rat_dst_h) - { + while (lines--) { + while (dy < rat_dst_h) { uint16_t *dst16 = (uint16_t *)dst; uint16_t *pblend = (uint16_t *)blend_args.blend_line; int col = w; @@ -1012,42 +954,31 @@ static void scaleAA(void *__restrict src, void *__restrict dst, uint32_t w, uint if (!lines) pnext -= (pitch / sizeof(uint16_t)); - if (dy > rat_dst_h - bh[0]) - { + if (dy > rat_dst_h - bh[0]) { pblend = pnext; - } - else if (dy <= bh[0]) - { + } else if (dy <= bh[0]) { /* Drops const, won't get touched later though */ pblend = (uint16_t *)src; - } - else - { + } else { const uint32_t *src32 = (const uint32_t *)src; const uint32_t *pnext32 = (const uint32_t *)pnext; uint32_t *pblend32 = (uint32_t *)pblend; int count = w / 2; - if (dy <= bh[1]) - { + if (dy <= bh[1]) { const uint32_t *tmp = pnext32; pnext32 = src32; src32 = tmp; } - if (dy > rat_dst_h - bh[1] || dy <= bh[1]) - { - while (count--) - { + if (dy > rat_dst_h - bh[1] || dy <= bh[1]) { + while (count--) { *pblend32++ = AVERAGE32_1_3(*src32, *pnext32); src32++; pnext32++; } - } - else - { - while (count--) - { + } else { + while (count--) { *pblend32++ = AVERAGE32(*src32, *pnext32); src32++; pnext32++; @@ -1055,35 +986,23 @@ static void scaleAA(void *__restrict src, void *__restrict dst, uint32_t w, uint } } - while (col--) - { + while (col--) { uint16_t a, b, out; a = *pblend; b = *(pblend + 1); - while (dx < rat_dst_w) - { - if (a == b) - { + while (dx < rat_dst_w) { + if (a == b) { out = a; - } - else if (dx > rat_dst_w - bw[0]) - { // top quintile, bbbb + } else if (dx > rat_dst_w - bw[0]) { // top quintile, bbbb out = b; - } - else if (dx <= bw[0]) - { // last quintile, aaaa + } else if (dx <= bw[0]) { // last quintile, aaaa out = a; - } - else - { - if (dx > rat_dst_w - bw[1]) - { // 2nd quintile, abbb + } else { + if (dx > rat_dst_w - bw[1]) { // 2nd quintile, abbb a = AVERAGE16_NOCHK(a, b); - } - else if (dx <= bw[1]) - { // 4th quintile, aaab + } else if (dx <= bw[1]) { // 4th quintile, aaab b = AVERAGE16_NOCHK(a, b); } @@ -1115,9 +1034,11 @@ scaler_t GFX_getAAScaler(GFX_Renderer *renderer) blend_args.w_ratio_in = renderer->src_w / gcd_w; blend_args.w_ratio_out = renderer->dst_w / gcd_w; - double blend_denominator = (renderer->src_w > renderer->dst_w) ? 5 : 2.5; // TODO: these values are really only good for the nano... + double blend_denominator = + (renderer->src_w > renderer->dst_w) ? 5 : 2.5; // TODO: these values are really only good for the nano... // blend_denominator = 5.0; // better for trimui - // LOG_info("blend_denominator: %f (%i && %i)\n", blend_denominator, HAS_SKINNY_SCREEN, renderer->dst_w>renderer->src_w); + // LOG_info("blend_denominator: %f (%i && %i)\n", blend_denominator, HAS_SKINNY_SCREEN, + // renderer->dst_w>renderer->src_w); div_w = round(blend_args.w_ratio_out / blend_denominator); blend_args.w_bp[0] = div_w; @@ -1135,8 +1056,7 @@ scaler_t GFX_getAAScaler(GFX_Renderer *renderer) } void GFX_freeAAScaler(void) { - if (blend_args.blend_line != NULL) - { + if (blend_args.blend_line != NULL) { free(blend_args.blend_line); blend_args.blend_line = NULL; } @@ -1156,8 +1076,7 @@ SDL_Color /*GFX_*/ uintToColour(uint32_t colour) SDL_Rect GFX_blitScaled(int scale, SDL_Surface *src, SDL_Surface *dst) { - switch (scale) - { + switch (scale) { case GFX_SCALE_FIT: return GFX_blitScaleAspect(src, dst); break; @@ -1172,8 +1091,7 @@ SDL_Rect GFX_blitScaled(int scale, SDL_Surface *src, SDL_Surface *dst) SDL_Rect GFX_blitStretch(SDL_Surface *src, SDL_Surface *dst) { - if (!src || !dst) - { + if (!src || !dst) { SDL_Rect none = {0, 0}; return none; } @@ -1192,14 +1110,11 @@ static inline SDL_Rect GFX_scaledRectAspect(SDL_Rect src, SDL_Rect dst) float preview_aspect = (float)dst.w / (float)dst.h; // Determine scaling factor - if (image_aspect > preview_aspect) - { + if (image_aspect > preview_aspect) { // Image is wider than the preview area scaled_rect.w = dst.w; scaled_rect.h = (int)(dst.w / image_aspect); - } - else - { + } else { // Image is taller than or equal to the preview area scaled_rect.h = dst.h; scaled_rect.w = (int)(dst.h * image_aspect); @@ -1214,8 +1129,7 @@ static inline SDL_Rect GFX_scaledRectAspect(SDL_Rect src, SDL_Rect dst) SDL_Rect GFX_blitScaleAspect(SDL_Surface *src, SDL_Surface *dst) { - if (!src || !dst) - { + if (!src || !dst) { SDL_Rect none = {0, 0}; return none; } @@ -1237,13 +1151,10 @@ static inline SDL_Rect GFX_scaledRectAspectFill(SDL_Rect src, SDL_Rect dst) float preview_aspect = (float)dst.w / (float)dst.h; // Determine scaling factor - if (preview_aspect > image_aspect) - { + if (preview_aspect > image_aspect) { scaled_rect.w = src.w; scaled_rect.h = (int)(src.w / preview_aspect + 0.5f); - } - else - { + } else { scaled_rect.w = (int)(src.h * preview_aspect + 0.5f); scaled_rect.h = src.h; } @@ -1260,8 +1171,7 @@ static inline SDL_Rect GFX_scaledRectAspectFill(SDL_Rect src, SDL_Rect dst) SDL_Rect GFX_blitScaleToFill(SDL_Surface *src, SDL_Surface *dst) { - if (!src || !dst) - { + if (!src || !dst) { SDL_Rect none = {0, 0}; return none; } @@ -1285,8 +1195,7 @@ void GFX_ApplyRoundedCorners16(SDL_Surface *surface, SDL_Rect *rect, int radius) if (rect) target = *rect; - if (fmt->format != SDL_PIXELFORMAT_RGBA8888) - { + if (fmt->format != SDL_PIXELFORMAT_RGBA8888) { SDL_Log("Unsupported pixel format: %s", SDL_GetPixelFormatName(fmt->format)); return; } @@ -1298,16 +1207,11 @@ void GFX_ApplyRoundedCorners16(SDL_Surface *surface, SDL_Rect *rect, int radius) const int xEnd = target.x + target.w; const int yBeg = target.y; const int yEnd = target.y + target.h; - for (int y = yBeg; y < yEnd; ++y) - { - for (int x = xBeg; x < xEnd; ++x) - { - int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) - : 0; - int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) - : 0; - if (dx * dx + dy * dy > radius * radius) - { + for (int y = yBeg; y < yEnd; ++y) { + for (int x = xBeg; x < xEnd; ++x) { + int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) : 0; + int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) : 0; + if (dx * dx + dy * dy > radius * radius) { pixels[y * (surface->pitch / 2) + x] = transparent_black; // Set to black (0) } } @@ -1331,16 +1235,11 @@ void GFX_ApplyRoundedCorners(SDL_Surface *surface, SDL_Rect *rect, int radius) const int xEnd = target.x + target.w; const int yBeg = target.y; const int yEnd = target.y + target.h; - for (int y = yBeg; y < yEnd; ++y) - { - for (int x = xBeg; x < xEnd; ++x) - { - int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) - : 0; - int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) - : 0; - if (dx * dx + dy * dy > radius * radius) - { + for (int y = yBeg; y < yEnd; ++y) { + for (int x = xBeg; x < xEnd; ++x) { + int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) : 0; + int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) : 0; + if (dx * dx + dy * dy > radius * radius) { pixels[y * target.w + x] = transparent_black; // Set to fully transparent black } } @@ -1365,16 +1264,11 @@ void GFX_ApplyRoundedCorners_RGBA4444(SDL_Surface *surface, SDL_Rect *rect, int const int xEnd = target.x + target.w; const int yBeg = target.y; const int yEnd = target.y + target.h; - for (int y = yBeg; y < yEnd; ++y) - { - for (int x = xBeg; x < xEnd; ++x) - { - int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) - : 0; - int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) - : 0; - if (dx * dx + dy * dy > radius * radius) - { + for (int y = yBeg; y < yEnd; ++y) { + for (int x = xBeg; x < xEnd; ++x) { + int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) : 0; + int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) : 0; + if (dx * dx + dy * dy > radius * radius) { pixels[y * pitch + x] = transparent_black; } } @@ -1400,18 +1294,13 @@ void GFX_ApplyRoundedCorners_RGBA8888(SDL_Surface *surface, SDL_Rect *rect, int const int yBeg = target.y; const int yEnd = target.y + target.h; - for (int y = yBeg; y < yEnd; ++y) - { - for (int x = xBeg; x < xEnd; ++x) - { - int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) - : 0; - int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) - : 0; + for (int y = yBeg; y < yEnd; ++y) { + for (int x = xBeg; x < xEnd; ++x) { + int dx = (x < xBeg + radius) ? xBeg + radius - x : (x >= xEnd - radius) ? x - (xEnd - radius - 1) : 0; + int dy = (y < yBeg + radius) ? yBeg + radius - y : (y >= yEnd - radius) ? y - (yEnd - radius - 1) : 0; // Check if the pixel is outside the rounded corner radius - if (dx * dx + dy * dy > radius * radius) - { + if (dx * dx + dy * dy > radius * radius) { pixels[y * pitch + x] = transparent_black; } } @@ -1427,13 +1316,11 @@ void BlitRGBA4444toRGB565(SDL_Surface *src, SDL_Surface *dest, SDL_Rect *dest_re int width = src->w; int height = src->h; - for (int y = 0; y < height; ++y) - { + for (int y = 0; y < height; ++y) { Uint16 *srcRow = (Uint16 *)(srcPixels + y * src->pitch); Uint16 *destRow = (Uint16 *)(destPixels + (y + dest_rect->y) * dest->pitch); - for (int x = 0; x < width; ++x) - { + for (int x = 0; x < width; ++x) { Uint16 srcPixel = srcRow[x]; Uint8 r = (srcPixel >> 12) & 0xF; @@ -1448,19 +1335,15 @@ void BlitRGBA4444toRGB565(SDL_Surface *src, SDL_Surface *dest, SDL_Rect *dest_re int destX = x + dest_rect->x; int destY = y + dest_rect->y; - if (destX >= 0 && destX < dest->w && destY >= 0 && destY < dest->h) - { + if (destX >= 0 && destX < dest->w && destY >= 0 && destY < dest->h) { Uint16 *destPixelPtr = &destRow[destX]; if (a == 0) continue; - if (a == 15) - { + if (a == 15) { *destPixelPtr = (r << 11) | (g << 5) | b; - } - else - { + } else { Uint16 existingPixel = *destPixelPtr; Uint8 destR = (existingPixel >> 11) & 0x1F; @@ -1478,11 +1361,11 @@ void BlitRGBA4444toRGB565(SDL_Surface *src, SDL_Surface *dest, SDL_Rect *dest_re } } -void GFX_blitSurfaceColor(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color) +void GFX_blitSurfaceColor(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect, + uint32_t asset_color) { // This could be a RAII - if (asset_color != RGB_WHITE) - { + if (asset_color != RGB_WHITE) { // TODO: Is there a neat way to get the opposite effect of SDL_MapRGB? // This is kinda ugly and not very generic. if (asset_color == THEME_COLOR1) @@ -1502,22 +1385,16 @@ void GFX_blitSurfaceColor(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface *dst SDL_Color restore; SDL_GetSurfaceColorMod(src, &restore.r, &restore.g, &restore.b); - SDL_SetSurfaceColorMod(src, - (asset_color >> 16) & 0xFF, - (asset_color >> 8) & 0xFF, - asset_color & 0xFF); + SDL_SetSurfaceColorMod(src, (asset_color >> 16) & 0xFF, (asset_color >> 8) & 0xFF, asset_color & 0xFF); SDL_BlitSurface(src, src_rect, dst, dst_rect); SDL_SetSurfaceColorMod(src, restore.r, restore.g, restore.b); - } - else - { + } else { SDL_BlitSurface(src, src_rect, dst, dst_rect); } } void GFX_blitAssetColor(int asset, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color) { - SDL_Rect *rect = &asset_rects[asset]; SDL_Rect adj_rect = { .x = rect->x, @@ -1525,8 +1402,7 @@ void GFX_blitAssetColor(int asset, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rec .w = rect->w, .h = rect->h, }; - if (src_rect) - { + if (src_rect) { adj_rect.x += src_rect->x; adj_rect.y += src_rect->y; adj_rect.w = src_rect->w; @@ -1556,8 +1432,7 @@ void GFX_blitPillColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t GFX_blitAssetColor(asset, &(SDL_Rect){0, 0, r, h}, dst, &(SDL_Rect){x, y}, asset_color); x += r; - if (w > 0) - { + if (w > 0) { // SDL_FillRect(dst, &(SDL_Rect){x,y,w,h}, UintMult(fill_color, asset_color)); SDL_FillRect(dst, &(SDL_Rect){x, y, w, h}, asset_color); x += w; @@ -1610,8 +1485,7 @@ void GFX_blitBattery(SDL_Surface *dst, SDL_Rect *dst_rect) { int x = 0; int y = 0; - if (dst_rect) - { + if (dst_rect) { x = dst_rect->x; y = dst_rect->y; } @@ -1625,12 +1499,9 @@ int GFX_getButtonWidth(char *hint, char *button) int special_case = !strcmp(button, BRIGHTNESS_BUTTON_LABEL); // TODO: oof - if (strlen(button) == 1) - { + if (strlen(button) == 1) { button_width += SCALE1(BUTTON_SIZE); - } - else - { + } else { button_width += SCALE1(BUTTON_SIZE) / 2; TTF_SizeUTF8(special_case ? font.large : font.tiny, button, &width, NULL); button_width += width; @@ -1649,24 +1520,26 @@ void GFX_blitButton(char *hint, char *button, SDL_Surface *dst, SDL_Rect *dst_re int special_case = !strcmp(button, BRIGHTNESS_BUTTON_LABEL); // TODO: oof // button - if (strlen(button) == 1) - { + if (strlen(button) == 1) { GFX_blitAssetColor(ASSET_BUTTON, NULL, dst, dst_rect, THEME_COLOR1); // label text = TTF_RenderUTF8_Blended(font.medium, button, ALT_BUTTON_TEXT_COLOR); - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){dst_rect->x + (SCALE1(BUTTON_SIZE) - text->w) / 2, dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2}); + SDL_BlitSurface(text, NULL, dst, + &(SDL_Rect){dst_rect->x + (SCALE1(BUTTON_SIZE) - text->w) / 2, + dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2}); ox += SCALE1(BUTTON_SIZE); SDL_FreeSurface(text); - } - else - { + } else { text = TTF_RenderUTF8_Blended(special_case ? font.large : font.tiny, button, ALT_BUTTON_TEXT_COLOR); - GFX_blitPillDark(ASSET_BUTTON, dst, &(SDL_Rect){dst_rect->x, dst_rect->y, SCALE1(BUTTON_SIZE) / 2 + text->w, SCALE1(BUTTON_SIZE)}); + GFX_blitPillDark(ASSET_BUTTON, dst, + &(SDL_Rect){dst_rect->x, dst_rect->y, SCALE1(BUTTON_SIZE) / 2 + text->w, SCALE1(BUTTON_SIZE)}); ox += SCALE1(BUTTON_SIZE) / 4; int oy = special_case ? SCALE1(-2) : 0; - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){ox + dst_rect->x, oy + dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2, text->w, text->h}); + SDL_BlitSurface( + text, NULL, dst, + &(SDL_Rect){ox + dst_rect->x, oy + dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2, text->w, text->h}); ox += text->w; ox += SCALE1(BUTTON_SIZE) / 4; SDL_FreeSurface(text); @@ -1677,7 +1550,8 @@ void GFX_blitButton(char *hint, char *button, SDL_Surface *dst, SDL_Rect *dst_re // hint text SDL_Color text_color = uintToColour(THEME_COLOR6_255); text = TTF_RenderUTF8_Blended(font.small, hint, text_color); - SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){ox + dst_rect->x, dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2, text->w, text->h}); + SDL_BlitSurface(text, NULL, dst, + &(SDL_Rect){ox + dst_rect->x, dst_rect->y + (SCALE1(BUTTON_SIZE) - text->h) / 2, text->w, text->h}); SDL_FreeSurface(text); } void GFX_blitMessage(TTF_Font *font, char *msg, SDL_Surface *dst, SDL_Rect *dst_rect) @@ -1694,8 +1568,7 @@ void GFX_blitMessage(TTF_Font *font, char *msg, SDL_Surface *dst, SDL_Rect *dst_ char *tmp; rows[row_count++] = msg; - while ((tmp = strchr(rows[row_count - 1], '\n')) != NULL) - { + while ((tmp = strchr(rows[row_count - 1], '\n')) != NULL) { if (row_count + 1 >= TEXT_BOX_MAX_ROWS) return; // TODO: bail rows[row_count++] = tmp + 1; @@ -1707,24 +1580,19 @@ void GFX_blitMessage(TTF_Font *font, char *msg, SDL_Surface *dst, SDL_Rect *dst_ y += (dst_rect->h - rendered_height) / 2; char line[256]; - for (int i = 0; i < row_count; i++) - { + for (int i = 0; i < row_count; i++) { int len; - if (i + 1 < row_count) - { + if (i + 1 < row_count) { len = rows[i + 1] - rows[i] - 1; if (len) strncpy(line, rows[i], len); line[len] = '\0'; - } - else - { + } else { len = strlen(rows[i]); strcpy(line, rows[i]); } - if (len) - { + if (len) { text = TTF_RenderUTF8_Blended_Wrapped(font, line, COLOR_WHITE, dst_rect->w); int x = dst_rect->x; x += (dst_rect->w - text->w) / 2; @@ -1739,35 +1607,27 @@ void GFX_blitBatteryAtPosition(SDL_Surface *dst, int x, int y) { SDL_Rect battery_rect = asset_rects[ASSET_BATTERY]; - if (pwr.is_charging) - { + if (pwr.is_charging) { GFX_blitAssetColor(ASSET_BATTERY, NULL, dst, &(SDL_Rect){x, y}, THEME_COLOR6); GFX_blitAssetColor(ASSET_BATTERY_BOLT, NULL, dst, &(SDL_Rect){x + SCALE1(3), y + SCALE1(2)}, THEME_COLOR6); - } - else - { + } else { int percent = pwr.charge; - GFX_blitAssetColor(percent <= 10 ? ASSET_BATTERY_LOW : ASSET_BATTERY, NULL, dst, &(SDL_Rect){x, y}, THEME_COLOR6); + GFX_blitAssetColor(percent <= 10 ? ASSET_BATTERY_LOW : ASSET_BATTERY, NULL, dst, &(SDL_Rect){x, y}, + THEME_COLOR6); - if (CFG_getShowBatteryPercent()) - { + if (CFG_getShowBatteryPercent()) { char percentage[16]; sprintf(percentage, "%i", pwr.charge); SDL_Surface *text = TTF_RenderUTF8_Blended(font.micro, percentage, uintToColour(THEME_COLOR6_255)); - SDL_Rect target = { - x + (battery_rect.w - text->w) / 2 + 1, - y + (battery_rect.h - text->h) / 2 - 1}; + SDL_Rect target = {x + (battery_rect.w - text->w) / 2 + 1, y + (battery_rect.h - text->h) / 2 - 1}; SDL_BlitSurface(text, NULL, dst, &target); SDL_FreeSurface(text); - } - else - { + } else { SDL_Rect fill_rect = asset_rects[ASSET_BATTERY_FILL]; SDL_Rect clip = fill_rect; clip.w *= percent; clip.w /= 100; - if (clip.w > 0) - { + if (clip.w > 0) { clip.x = fill_rect.w - clip.w; clip.y = 0; GFX_blitAssetColor(percent <= 20 ? ASSET_BATTERY_FILL_LOW : ASSET_BATTERY_FILL, &clip, dst, @@ -1787,34 +1647,28 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) int setting_min; int setting_max; - if (show_setting && !GetHDMI()) - { + if (show_setting && !GetHDMI()) { int asset; ow = SCALE1(PILL_SIZE + SETTINGS_WIDTH + 10 + 4); ox = dst->w - SCALE1(PADDING) - ow; oy = SCALE1(PADDING); GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE); - if (show_setting == 1) - { + if (show_setting == 1) { setting_value = GetBrightness(); setting_min = BRIGHTNESS_MIN; setting_max = BRIGHTNESS_MAX; asset = ASSET_BRIGHTNESS; - } - else if (show_setting == 3) - { + } else if (show_setting == 3) { setting_value = GetColortemp(); setting_min = COLORTEMP_MIN; setting_max = COLORTEMP_MAX; asset = ASSET_COLORTEMP; - } - else - { + } else { setting_value = GetVolume(); setting_min = VOLUME_MIN; setting_max = VOLUME_MAX; - if(GetAudioSink() == AUDIO_SINK_BLUETOOTH) + if (GetAudioSink() == AUDIO_SINK_BLUETOOTH) asset = (setting_value > 0 ? ASSET_BLUETOOTH : ASSET_BLUETOOTH_OFF); else asset = (setting_value > 0 ? ASSET_VOLUME : ASSET_VOLUME_MUTE); @@ -1828,17 +1682,15 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) ox += SCALE1(PILL_SIZE); oy += SCALE1((PILL_SIZE - SETTINGS_SIZE) / 2); - GFX_blitPillColor(gfx.mode == MODE_MAIN ? ASSET_BAR_BG : ASSET_BAR_BG_MENU, dst, &(SDL_Rect){ox, oy, SCALE1(SETTINGS_WIDTH), SCALE1(SETTINGS_SIZE)}, - THEME_COLOR3, RGB_WHITE); + GFX_blitPillColor(gfx.mode == MODE_MAIN ? ASSET_BAR_BG : ASSET_BAR_BG_MENU, dst, + &(SDL_Rect){ox, oy, SCALE1(SETTINGS_WIDTH), SCALE1(SETTINGS_SIZE)}, THEME_COLOR3, RGB_WHITE); float percent = ((float)(setting_value - setting_min) / (setting_max - setting_min)); - if (show_setting == 1 || show_setting == 3 || setting_value > 0) - { - GFX_blitPillDark(ASSET_BAR, dst, &(SDL_Rect){ox, oy, SCALE1(SETTINGS_WIDTH) * percent, SCALE1(SETTINGS_SIZE)}); + if (show_setting == 1 || show_setting == 3 || setting_value > 0) { + GFX_blitPillDark(ASSET_BAR, dst, + &(SDL_Rect){ox, oy, SCALE1(SETTINGS_WIDTH) * percent, SCALE1(SETTINGS_SIZE)}); } - } - else - { + } else { ConnectionStrength strength = PLAT_connectionStrength(); int show_wifi = strength > SIGNAL_STRENGTH_OFF; // no need to handle in PLAT_updateNetworkStatus, @@ -1847,31 +1699,27 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) bool show_clock = CFG_getShowClock(); SDL_Rect battery_rect = asset_rects[ASSET_BATTERY]; - if (!show_bt && !show_wifi && !show_clock) - { + if (!show_bt && !show_wifi && !show_clock) { ow = SCALE1(PILL_SIZE); ox = dst->w - SCALE1(PADDING) - ow; oy = SCALE1(PADDING); - GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE); + GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, + RGB_WHITE); int battery_x = ox + (SCALE1(PILL_SIZE) - (battery_rect.w + FIXED_SCALE)) / 2; int battery_y = oy + (SCALE1(PILL_SIZE) - battery_rect.h) / 2; GFX_blitBatteryAtPosition(dst, battery_x, battery_y); - } - else - { + } else { ow = SCALE1(BUTTON_MARGIN); - if (show_bt) - { + if (show_bt) { SDL_Rect bt_rect = asset_rects[ASSET_BLUETOOTH]; ow += bt_rect.w + SCALE1(BUTTON_MARGIN); } - if (show_wifi) - { + if (show_wifi) { SDL_Rect wifi_rect = asset_rects[ASSET_WIFI]; ow += wifi_rect.w + SCALE1(BUTTON_MARGIN); } @@ -1879,8 +1727,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) ow += battery_rect.w + SCALE1(BUTTON_MARGIN); SDL_Surface *clock = NULL; - if (show_clock) - { + if (show_clock) { int clock_width = 0; char timeString[12]; time_t t = time(NULL); @@ -1897,12 +1744,12 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) ox = dst->w - SCALE1(PADDING) - ow; oy = SCALE1(PADDING); - GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, RGB_WHITE); + GFX_blitPillColor(ASSET_WHITE_PILL, dst, &(SDL_Rect){ox, oy, ow, SCALE1(PILL_SIZE)}, THEME_COLOR2, + RGB_WHITE); ox += SCALE1(BUTTON_MARGIN); - if (show_bt) - { + if (show_bt) { int asset = ASSET_BLUETOOTH; SDL_Rect bt_rect = asset_rects[asset]; int x = ox; @@ -1912,12 +1759,12 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) ox += bt_rect.w + SCALE1(BUTTON_MARGIN); } - if (show_wifi) - { - int asset = - strength == SIGNAL_STRENGTH_HIGH ? ASSET_WIFI : strength == SIGNAL_STRENGTH_MED ? ASSET_WIFI_MED - : strength == SIGNAL_STRENGTH_LOW ? ASSET_WIFI_LOW - : ASSET_WIFI_OFF; // this should use ASSET_WIFI and be greyed out + if (show_wifi) { + int asset = strength == SIGNAL_STRENGTH_HIGH ? ASSET_WIFI + : strength == SIGNAL_STRENGTH_MED ? ASSET_WIFI_MED + : strength == SIGNAL_STRENGTH_LOW + ? ASSET_WIFI_LOW + : ASSET_WIFI_OFF; // this should use ASSET_WIFI and be greyed out SDL_Rect wifi_rect = asset_rects[asset]; int x = ox; int y = oy + (SCALE1(PILL_SIZE) - wifi_rect.h) / 2; @@ -1932,8 +1779,7 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) GFX_blitBatteryAtPosition(dst, battery_x, battery_y); ox += battery_rect.w + SCALE1(BUTTON_MARGIN); - if (show_clock && clock) - { + if (show_clock && clock) { int x = ox; int y = oy + (SCALE1(PILL_SIZE) - clock->h) / 2; SDL_BlitSurface(clock, NULL, dst, &(SDL_Rect){x, y}); @@ -1946,7 +1792,6 @@ int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting) } void GFX_blitHardwareHints(SDL_Surface *dst, int show_setting) { - if (show_setting == 1) GFX_blitButtonGroup((char *[]){BRIGHTNESS_BUTTON_LABEL, "BRIGHTNESS", NULL}, 0, dst, 0); else if (show_setting == 3) @@ -1963,8 +1808,7 @@ int GFX_blitButtonGroup(char **pairs, int primary, SDL_Surface *dst, int align_r char *hint; char *button; - struct Hint - { + struct Hint { char *hint; char *button; int ow; @@ -1975,8 +1819,7 @@ int GFX_blitButtonGroup(char **pairs, int primary, SDL_Surface *dst, int align_r ox = align_right ? dst->w - SCALE1(PADDING) : SCALE1(PADDING); oy = dst->h - SCALE1(PADDING + PILL_SIZE); - for (int i = 0; i < 2; i++) - { + for (int i = 0; i < 2; i++) { if (!pairs[i * 2]) break; if (HAS_SKINNY_SCREEN && i != primary) @@ -1999,8 +1842,7 @@ int GFX_blitButtonGroup(char **pairs, int primary, SDL_Surface *dst, int align_r ox += SCALE1(BUTTON_MARGIN); oy += SCALE1(BUTTON_MARGIN); - for (int i = 0; i < h; i++) - { + for (int i = 0; i < h; i++) { GFX_blitButton(hints[i].hint, hints[i].button, dst, &(SDL_Rect){ox, oy}); ox += hints[i].ow + SCALE1(BUTTON_MARGIN); } @@ -2015,8 +1857,7 @@ void GFX_sizeText(TTF_Font *font, const char *str, int leading, int *w, int *h) const char *tmp; lines[count++] = str; - while ((tmp = strchr(lines[count - 1], '\n')) != NULL) - { + while ((tmp = strchr(lines[count - 1], '\n')) != NULL) { if (count + 1 > MAX_TEXT_LINES) break; // TODO: bail? lines[count++] = tmp + 1; @@ -2025,24 +1866,19 @@ void GFX_sizeText(TTF_Font *font, const char *str, int leading, int *w, int *h) int mw = 0; char line[256]; - for (int i = 0; i < count; i++) - { + for (int i = 0; i < count; i++) { int len; - if (i + 1 < count) - { + if (i + 1 < count) { len = lines[i + 1] - lines[i] - 1; if (len) strncpy(line, lines[i], len); line[len] = '\0'; - } - else - { + } else { len = strlen(lines[i]); strcpy(line, lines[i]); } - if (len) - { + if (len) { int lw; TTF_SizeUTF8(font, line, &lw, NULL); if (lw > mw) @@ -2061,8 +1897,7 @@ void GFX_blitText(TTF_Font *font, const char *str, int leading, SDL_Color color, const char *tmp; lines[count++] = str; - while ((tmp = strchr(lines[count - 1], '\n')) != NULL) - { + while ((tmp = strchr(lines[count - 1], '\n')) != NULL) { if (count + 1 > MAX_TEXT_LINES) break; // TODO: bail? lines[count++] = tmp + 1; @@ -2072,24 +1907,19 @@ void GFX_blitText(TTF_Font *font, const char *str, int leading, SDL_Color color, SDL_Surface *text; char line[256]; - for (int i = 0; i < count; i++) - { + for (int i = 0; i < count; i++) { int len; - if (i + 1 < count) - { + if (i + 1 < count) { len = lines[i + 1] - lines[i] - 1; if (len) strncpy(line, lines[i], len); line[len] = '\0'; - } - else - { + } else { len = strlen(lines[i]); strcpy(line, lines[i]); } - if (len) - { + if (len) { text = TTF_RenderUTF8_Blended(font, line, color); SDL_BlitSurface(text, NULL, dst, &(SDL_Rect){x + ((dst_rect->w - text->w) / 2), y + (i * leading)}); SDL_FreeSurface(text); @@ -2130,8 +1960,7 @@ static void SND_audioCallback(void *userdata, uint8_t *stream, int len) len /= (sizeof(int16_t) * 2); pthread_mutex_lock(&audio_mutex); - while (snd.frame_out != snd.frame_in && len > 0) - { + while (snd.frame_out != snd.frame_in && len > 0) { *out++ = snd.buffer[snd.frame_out].left; *out++ = snd.buffer[snd.frame_out].right; snd.frame_out += 1; @@ -2182,35 +2011,27 @@ void SND_setQuality(int quality) soundQuality = qualityLevels[quality]; resetSrcState = 1; } -ResampledFrames resample_audio(const SND_Frame *input_frames, - int input_frame_count, int input_sample_rate, +ResampledFrames resample_audio(const SND_Frame *input_frames, int input_frame_count, int input_sample_rate, int output_sample_rate, double ratio) { - int error; static double previous_ratio = 1.0; static SRC_STATE *src_state = NULL; double final_ratio = ((double)output_sample_rate / input_sample_rate) * ratio; - if (!src_state || resetSrcState) - { + if (!src_state || resetSrcState) { resetSrcState = 0; src_state = src_new(soundQuality, 2, &error); - if (src_state == NULL) - { - fprintf(stderr, "Error initializing SRC state: %s\n", - src_strerror(error)); + if (src_state == NULL) { + fprintf(stderr, "Error initializing SRC state: %s\n", src_strerror(error)); exit(1); } } - if (previous_ratio != final_ratio) - { - if (src_set_ratio(src_state, final_ratio) != 0) - { - fprintf(stderr, "Error setting resampling ratio: %s\n", - src_strerror(src_error(src_state))); + if (previous_ratio != final_ratio) { + if (src_set_ratio(src_state, final_ratio) != 0) { + fprintf(stderr, "Error setting resampling ratio: %s\n", src_strerror(src_error(src_state))); exit(1); } previous_ratio = final_ratio; @@ -2220,8 +2041,7 @@ ResampledFrames resample_audio(const SND_Frame *input_frames, float *input_buffer = (float *)malloc(input_frame_count * 2 * sizeof(float)); float *output_buffer = (float *)malloc(max_output_frames * 2 * sizeof(float)); - if (!input_buffer || !output_buffer) - { + if (!input_buffer || !output_buffer) { fprintf(stderr, "Error allocating buffers\n"); free(input_buffer); free(output_buffer); @@ -2229,24 +2049,20 @@ ResampledFrames resample_audio(const SND_Frame *input_frames, exit(1); } - for (int i = 0; i < input_frame_count; i++) - { + for (int i = 0; i < input_frame_count; i++) { input_buffer[2 * i] = input_frames[i].left / 32768.0f; input_buffer[2 * i + 1] = input_frames[i].right / 32768.0f; } - SRC_DATA src_data = { - .data_in = input_buffer, - .data_out = output_buffer, - .input_frames = input_frame_count, - .output_frames = max_output_frames, - .src_ratio = final_ratio, - .end_of_input = 0}; - - if (src_process(src_state, &src_data) != 0) - { - fprintf(stderr, "Error resampling: %s\n", - src_strerror(src_error(src_state))); + SRC_DATA src_data = {.data_in = input_buffer, + .data_out = output_buffer, + .input_frames = input_frame_count, + .output_frames = max_output_frames, + .src_ratio = final_ratio, + .end_of_input = 0}; + + if (src_process(src_state, &src_data) != 0) { + fprintf(stderr, "Error resampling: %s\n", src_strerror(src_error(src_state))); free(input_buffer); free(output_buffer); exit(1); @@ -2255,16 +2071,14 @@ ResampledFrames resample_audio(const SND_Frame *input_frames, int output_frame_count = src_data.output_frames_gen; SND_Frame *output_frames = (SND_Frame *)malloc(output_frame_count * sizeof(SND_Frame)); - if (!output_frames) - { + if (!output_frames) { fprintf(stderr, "Error allocating output frames\n"); free(input_buffer); free(output_buffer); exit(1); } - for (int i = 0; i < output_frame_count; i++) - { + for (int i = 0; i < output_frame_count; i++) { float left = output_buffer[2 * i]; float right = output_buffer[2 * i + 1]; @@ -2295,13 +2109,11 @@ int avgbufferfree = 0; float calculateBufferAdjustment(float remaining_space, float targetbuffer_over, float targetbuffer_under, int batchsize) { - // this is just to show average remaining space in debug window could be removed later remaining_space_history[remaining_space_index] = remaining_space; remaining_space_index = (remaining_space_index + 1) % ROLLING_AVERAGE_WINDOW_SIZE; float avgspace = 0.0f; - for (int i = 0; i < ROLLING_AVERAGE_WINDOW_SIZE; ++i) - { + for (int i = 0; i < ROLLING_AVERAGE_WINDOW_SIZE; ++i) { avgspace += remaining_space_history[i]; } avgspace /= ROLLING_AVERAGE_WINDOW_SIZE; @@ -2312,23 +2124,20 @@ float calculateBufferAdjustment(float remaining_space, float targetbuffer_over, currentbuffertarget = midpoint; float normalizedDistance; - if (remaining_space < midpoint) - { + if (remaining_space < midpoint) { normalizedDistance = (midpoint - remaining_space) / (midpoint - targetbuffer_over); - } - else - { + } else { normalizedDistance = (remaining_space - midpoint) / (targetbuffer_under - midpoint); } - // I make crazy small adjustments, mooore tiny is mooore stable :D But don't come neir the limits cuz imma hit ya with that 0.005 ratio adjustment, pow pow! - // I wonder if staying in the middle of 0 to 4000 with 512 samples per batch playing at tiny different speeds each iteration is like the smallest I can get - // lets say hovering around 2000 means 2000 samples queue, about 4 frames, so at 17ms(60fps) thats 68ms delay right? - // Should have payed attention when my math teacher was talking dammit - // Also I chose 3 for pow, but idk if that really the best nr, anyone good in maths looking at my code? + // I make crazy small adjustments, mooore tiny is mooore stable :D But don't come neir the limits cuz imma hit ya + // with that 0.005 ratio adjustment, pow pow! I wonder if staying in the middle of 0 to 4000 with 512 samples per + // batch playing at tiny different speeds each iteration is like the smallest I can get lets say hovering around + // 2000 means 2000 samples queue, about 4 frames, so at 17ms(60fps) thats 68ms delay right? Should have payed + // attention when my math teacher was talking dammit Also I chose 3 for pow, but idk if that really the best nr, + // anyone good in maths looking at my code? float adjustment = 0.001f + (0.01f - 0.001f) * pow(normalizedDistance, 3); - if (remaining_space < midpoint) - { + if (remaining_space < midpoint) { adjustment = -adjustment; } @@ -2337,8 +2146,7 @@ float calculateBufferAdjustment(float remaining_space, float targetbuffer_over, // Calculate the rolling average float rolling_average = 0.0f; - for (int i = 0; i < ROLLING_AVERAGE_WINDOW_SIZE; ++i) - { + for (int i = 0; i < ROLLING_AVERAGE_WINDOW_SIZE; ++i) { rolling_average += adjustment_history[i]; } rolling_average /= ROLLING_AVERAGE_WINDOW_SIZE; @@ -2360,28 +2168,22 @@ size_t SND_batchSamples(const SND_Frame *frames, size_t frame_count) int total_consumed_frames = 0; double ratio = 1.0; - if (snd.frame_count <= 0) - { + if (snd.frame_count <= 0) { snd.frame_count = 4096; // idk some random samples nr this should never hit tho, just to be safe } - if (snd.frame_in < 0 || snd.frame_in >= snd.frame_count) - { + if (snd.frame_in < 0 || snd.frame_in >= snd.frame_count) { snd.frame_in = 0; } - if (snd.frame_out < 0 || snd.frame_out >= snd.frame_count) - { + if (snd.frame_out < 0 || snd.frame_out >= snd.frame_count) { snd.frame_out = 0; } float remaining_space = 0.0f; - if (snd.frame_in >= snd.frame_out) - { + if (snd.frame_in >= snd.frame_out) { remaining_space = snd.frame_count - (snd.frame_in - snd.frame_out); - } - else - { + } else { remaining_space = snd.frame_out - snd.frame_in; } currentbufferfree = remaining_space; @@ -2389,41 +2191,39 @@ size_t SND_batchSamples(const SND_Frame *frames, size_t frame_count) // let audio buffer fill a little first and then unpause audio so no underruns occur if (currentbufferfree < snd.frame_count * 0.6f) { SND_pauseAudio(false); - } else if (currentbufferfree > snd.frame_count * 0.99f) { // if for some reason buffer drops below threshold again, pause it (like psx core can stop sending audio in between scenes or after fast forward etc) + } else if (currentbufferfree > + snd.frame_count * 0.99f) { // if for some reason buffer drops below threshold again, pause it (like psx + // core can stop sending audio in between scenes or after fast forward etc) SND_pauseAudio(true); - } + } float tempdelay = ((snd.frame_count - remaining_space) / snd.sample_rate_out) * 1000.0f; currentbufferms = tempdelay; // do some checks - if (current_fps <= 0.0f || !isfinite(current_fps)) - { + if (current_fps <= 0.0f || !isfinite(current_fps)) { current_fps = 0.01f; } - if (!isfinite(snd.frame_rate) || snd.frame_rate <= 0.0f) - { + if (!isfinite(snd.frame_rate) || snd.frame_rate <= 0.0f) { snd.frame_rate = 60.0f; } - float bufferadjustment = calculateBufferAdjustment(remaining_space, snd.frame_count*0.2, snd.frame_count*0.8, frame_count); + float bufferadjustment = + calculateBufferAdjustment(remaining_space, snd.frame_count * 0.2, snd.frame_count * 0.8, frame_count); - if (!isfinite(bufferadjustment)) - { + if (!isfinite(bufferadjustment)) { bufferadjustment = 0.0f; } float safe_ratio = snd.frame_rate / current_fps; - if (!isfinite(safe_ratio)) - { + if (!isfinite(safe_ratio)) { safe_ratio = 1.0f; } ratio = safe_ratio + bufferadjustment; - if (!isfinite(ratio)) - { + if (!isfinite(ratio)) { ratio = 1.0; } @@ -2435,27 +2235,22 @@ size_t SND_batchSamples(const SND_Frame *frames, size_t frame_count) currentratio = (ratio > 0.0) ? ratio : current_fps; - while (framecount > 0) - { + while (framecount > 0) { int amount = MIN(BATCH_SIZE, framecount); // Copy frames to tmpbuffer for resampling - for (int i = 0; i < amount; i++) - { + for (int i = 0; i < amount; i++) { tmpbuffer[i] = frames[consumed + i]; } consumed += amount; framecount -= amount; - ResampledFrames resampled = resample_audio( - tmpbuffer, amount, snd.sample_rate_in, snd.sample_rate_out, ratio); + ResampledFrames resampled = resample_audio(tmpbuffer, amount, snd.sample_rate_in, snd.sample_rate_out, ratio); int written_frames = 0; - for (int i = 0; i < resampled.frame_count; i++) - { + for (int i = 0; i < resampled.frame_count; i++) { // Check if buffer full (leave one slot free) - if ((snd.frame_in + 1) % snd.frame_count == snd.frame_out) - { + if ((snd.frame_in + 1) % snd.frame_count == snd.frame_out) { // Buffer full, break early break; } @@ -2473,12 +2268,7 @@ size_t SND_batchSamples(const SND_Frame *frames, size_t frame_count) return total_consumed_frames; } -enum -{ - SND_FF_ON_TIME, - SND_FF_LATE, - SND_FF_VERY_LATE -}; +enum { SND_FF_ON_TIME, SND_FF_LATE, SND_FF_VERY_LATE }; size_t SND_batchSamples_fixed_rate(const SND_Frame *frames, size_t frame_count) { @@ -2495,55 +2285,48 @@ size_t SND_batchSamples_fixed_rate(const SND_Frame *frames, size_t frame_count) // int full = 0; float remaining_space = snd.frame_count; - if (snd.frame_in >= snd.frame_out) - { + if (snd.frame_in >= snd.frame_out) { remaining_space = snd.frame_count - (snd.frame_in - snd.frame_out); - } - else - { + } else { remaining_space = snd.frame_out - snd.frame_in; } // printf(" actual free: %g\n", remaining_space); currentbufferfree = remaining_space; - // let audio buffer fill up a little before playing audio, so no underruns occur. Target fill rate of buffer is about 50% so start playing when about 40% full + // let audio buffer fill up a little before playing audio, so no underruns occur. Target fill rate of buffer is + // about 50% so start playing when about 40% full if (currentbufferfree < snd.frame_count * 0.6f) { SND_pauseAudio(false); - } else if (currentbufferfree > snd.frame_count * 0.99f) { // if for some reason buffer drops below 1% again, pause audio again (like psx core can stop sending audio in between scenes or after fast forward etc) + } else if (currentbufferfree > + snd.frame_count * 0.99f) { // if for some reason buffer drops below 1% again, pause audio again (like psx + // core can stop sending audio in between scenes or after fast forward etc) SND_pauseAudio(true); - } + } float tempdelay = ((snd.frame_count - remaining_space) / snd.sample_rate_out) * 1000; currentbufferms = tempdelay; float occupancy = (float)(snd.frame_count - currentbufferfree) / snd.frame_count; - switch (current_mode) - { + switch (current_mode) { case SND_FF_ON_TIME: - if (occupancy > 0.65) - { + if (occupancy > 0.65) { current_mode = SND_FF_LATE; } break; case SND_FF_LATE: - if (occupancy > 0.85) - { + if (occupancy > 0.85) { current_mode = SND_FF_VERY_LATE; - } - else if (occupancy < 0.25) - { + } else if (occupancy < 0.25) { current_mode = SND_FF_ON_TIME; } break; case SND_FF_VERY_LATE: - if (occupancy < 0.50) - { + if (occupancy < 0.50) { current_mode = SND_FF_LATE; } break; } - switch (current_mode) - { + switch (current_mode) { case SND_FF_ON_TIME: ratio = 1.0; break; @@ -2560,28 +2343,22 @@ size_t SND_batchSamples_fixed_rate(const SND_Frame *frames, size_t frame_count) } currentratio = ratio; - while (framecount > 0) - { - + while (framecount > 0) { int amount = MIN(BATCH_SIZE, framecount); - for (int i = 0; i < amount; i++) - { + for (int i = 0; i < amount; i++) { tmpbuffer[i] = frames[consumed + i]; } consumed += amount; framecount -= amount; - ResampledFrames resampled = resample_audio( - tmpbuffer, amount, snd.sample_rate_in, snd.sample_rate_out, ratio); + ResampledFrames resampled = resample_audio(tmpbuffer, amount, snd.sample_rate_in, snd.sample_rate_out, ratio); // Write resampled frames to the buffer int written_frames = 0; - for (int i = 0; i < resampled.frame_count; i++) - { - if ((snd.frame_in + 1) % snd.frame_count == snd.frame_out) - { + for (int i = 0; i < resampled.frame_count; i++) { + if ((snd.frame_in + 1) % snd.frame_count == snd.frame_out) { // Buffer is full, break. This should never happen tho, but just to be safe break; } @@ -2602,7 +2379,7 @@ size_t SND_batchSamples_fixed_rate(const SND_Frame *frames, size_t frame_count) void SND_init(double sample_rate, double frame_rate) { // plat_sound_init LOG_info("SND_init\n"); - if(SDL_WasInit(SDL_INIT_AUDIO)) + if (SDL_WasInit(SDL_INIT_AUDIO)) LOG_error("SND_init: already initialized\n"); currentreqfps = frame_rate; SDL_InitSubSystem(SDL_INIT_AUDIO); @@ -2612,15 +2389,13 @@ void SND_init(double sample_rate, double frame_rate) #if defined(USE_SDL2) LOG_info("Available audio drivers:\n"); - for (int i = 0; i < SDL_GetNumAudioDrivers(); i++) - { + for (int i = 0; i < SDL_GetNumAudioDrivers(); i++) { LOG_info("- %s\n", SDL_GetAudioDriver(i)); } LOG_info("Current audio driver: %s\n", SDL_GetCurrentAudioDriver()); LOG_info("Available audio devices:\n"); - for (int i = 0; i < SDL_GetNumAudioDevices(0); i++) - { + for (int i = 0; i < SDL_GetNumAudioDevices(0); i++) { LOG_info("- %s\n", SDL_GetAudioDeviceName(i, 0)); } #endif @@ -2639,8 +2414,7 @@ void SND_init(double sample_rate, double frame_rate) #if defined(USE_SDL2) snd.device_id = SDL_OpenAudioDevice(NULL, 0, &spec_in, &spec_out, SDL_AUDIO_ALLOW_ANY_CHANGE); - if (snd.device_id <= 0) - { + if (snd.device_id <= 0) { LOG_info("SDL_OpenAudioDevice error: %s\n", SDL_GetError()); if (SDL_OpenAudio(&spec_in, &spec_out) < 0) { LOG_info("SDL_OpenAudio error: %s\n", SDL_GetError()); @@ -2659,7 +2433,8 @@ void SND_init(double sample_rate, double frame_rate) LOG_info("We now have audio device #%d\n", snd.device_id); - snd.frame_count = ((float)spec_out.freq / SCREEN_FPS) * 8; // buffer size based on sample rate out (times 12 samples headroom) + snd.frame_count = + ((float)spec_out.freq / SCREEN_FPS) * 8; // buffer size based on sample rate out (times 12 samples headroom) currentbuffersize = snd.frame_count; snd.sample_rate_in = sample_rate; snd.sample_rate_out = spec_out.freq; @@ -2672,13 +2447,11 @@ void SND_init(double sample_rate, double frame_rate) SND_pauseAudio(true); LOG_info("sample rate: %i (req) %i (rec) [samples %i]\n", snd.sample_rate_in, snd.sample_rate_out, SAMPLES); snd.initialized = 1; - } void SND_quit(void) { - if (!snd.initialized) - { + if (!snd.initialized) { LOG_warn("Skipping SND teardown, not initialized.\n"); return; } @@ -2692,13 +2465,12 @@ void SND_quit(void) #endif SDL_QuitSubSystem(SDL_INIT_AUDIO); - if(SDL_WasInit(SDL_INIT_AUDIO)) + if (SDL_WasInit(SDL_INIT_AUDIO)) LOG_error("SND_quit: failed to quit audio!!\n"); LOG_debug("SND_quit: quit audio!!\n"); snd.initialized = 0; - if (snd.buffer) - { + if (snd.buffer) { free(snd.buffer); snd.buffer = NULL; } @@ -2719,8 +2491,12 @@ void SND_pauseAudio(bool paused) #endif } -FALLBACK_IMPLEMENTATION void PLAT_audioDeviceWatchRegister(void (*cb)(int, int)) {} -FALLBACK_IMPLEMENTATION void PLAT_audioDeviceWatchUnregister(void) {} +FALLBACK_IMPLEMENTATION void PLAT_audioDeviceWatchRegister(void (*cb)(int, int)) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_audioDeviceWatchUnregister(void) +{ +} /////////////////////////////// @@ -2729,8 +2505,13 @@ LID_Context lid = { .is_open = 1, }; -FALLBACK_IMPLEMENTATION void PLAT_initLid(void) {} -FALLBACK_IMPLEMENTATION int PLAT_lidChanged(int *state) { return 0; } +FALLBACK_IMPLEMENTATION void PLAT_initLid(void) +{ +} +FALLBACK_IMPLEMENTATION int PLAT_lidChanged(int *state) +{ + return 0; +} /////////////////////////////// @@ -2742,50 +2523,39 @@ void PAD_setAnalog(int neg_id, int pos_id, int value, int repeat_at) // LOG_info("neg %i pos %i value %i\n", neg_id, pos_id, value); int neg = 1 << neg_id; int pos = 1 << pos_id; - if (value > AXIS_DEADZONE) - { // pressing - if (!(pad.is_pressed & pos)) - { // not pressing - pad.is_pressed |= pos; // set - pad.just_pressed |= pos; // set - pad.just_repeated |= pos; // set + if (value > AXIS_DEADZONE) { // pressing + if (!(pad.is_pressed & pos)) { // not pressing + pad.is_pressed |= pos; // set + pad.just_pressed |= pos; // set + pad.just_repeated |= pos; // set pad.repeat_at[pos_id] = repeat_at; - if (pad.is_pressed & neg) - { // was pressing opposite + if (pad.is_pressed & neg) { // was pressing opposite pad.is_pressed &= ~neg; // unset pad.just_repeated &= ~neg; // unset pad.just_released |= neg; // set } } - } - else if (value < -AXIS_DEADZONE) - { // pressing - if (!(pad.is_pressed & neg)) - { // not pressing - pad.is_pressed |= neg; // set - pad.just_pressed |= neg; // set - pad.just_repeated |= neg; // set + } else if (value < -AXIS_DEADZONE) { // pressing + if (!(pad.is_pressed & neg)) { // not pressing + pad.is_pressed |= neg; // set + pad.just_pressed |= neg; // set + pad.just_repeated |= neg; // set pad.repeat_at[neg_id] = repeat_at; - if (pad.is_pressed & pos) - { // was pressing opposite + if (pad.is_pressed & pos) { // was pressing opposite pad.is_pressed &= ~pos; // unset pad.just_repeated &= ~pos; // unset pad.just_released |= pos; // set } } - } - else - { // not pressing - if (pad.is_pressed & neg) - { // was pressing + } else { // not pressing + if (pad.is_pressed & neg) { // was pressing pad.is_pressed &= ~neg; // unset pad.just_repeated &= neg; // unset pad.just_released |= neg; // set } - if (pad.is_pressed & pos) - { // was pressing + if (pad.is_pressed & pos) { // was pressing pad.is_pressed &= ~pos; // unset pad.just_repeated &= pos; // unset pad.just_released |= pos; // set @@ -2809,11 +2579,9 @@ FALLBACK_IMPLEMENTATION void PLAT_pollInput(void) pad.just_repeated = BTN_NONE; uint32_t tick = SDL_GetTicks(); - for (int i = 0; i < BTN_ID_COUNT; i++) - { + for (int i = 0; i < BTN_ID_COUNT; i++) { int btn = 1 << i; - if ((pad.is_pressed & btn) && (tick >= pad.repeat_at[i])) - { + if ((pad.is_pressed & btn) && (tick >= pad.repeat_at[i])) { pad.just_repeated |= btn; // set pad.repeat_at[i] += PAD_REPEAT_INTERVAL; } @@ -2821,252 +2589,159 @@ FALLBACK_IMPLEMENTATION void PLAT_pollInput(void) // the actual poll SDL_Event event; - while (SDL_PollEvent(&event)) - { + while (SDL_PollEvent(&event)) { int btn = BTN_NONE; int pressed = 0; // 0=up,1=down int id = -1; - if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) - { + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { uint8_t code = event.key.keysym.scancode; pressed = event.type == SDL_KEYDOWN; // LOG_info("key event: %i (%i)\n", code,pressed); - if (code == CODE_UP) - { + if (code == CODE_UP) { btn = BTN_DPAD_UP; id = BTN_ID_DPAD_UP; - } - else if (code == CODE_DOWN) - { + } else if (code == CODE_DOWN) { btn = BTN_DPAD_DOWN; id = BTN_ID_DPAD_DOWN; - } - else if (code == CODE_LEFT) - { + } else if (code == CODE_LEFT) { btn = BTN_DPAD_LEFT; id = BTN_ID_DPAD_LEFT; - } - else if (code == CODE_RIGHT) - { + } else if (code == CODE_RIGHT) { btn = BTN_DPAD_RIGHT; id = BTN_ID_DPAD_RIGHT; - } - else if (code == CODE_A) - { + } else if (code == CODE_A) { btn = BTN_A; id = BTN_ID_A; - } - else if (code == CODE_B) - { + } else if (code == CODE_B) { btn = BTN_B; id = BTN_ID_B; - } - else if (code == CODE_X) - { + } else if (code == CODE_X) { btn = BTN_X; id = BTN_ID_X; - } - else if (code == CODE_Y) - { + } else if (code == CODE_Y) { btn = BTN_Y; id = BTN_ID_Y; - } - else if (code == CODE_START) - { + } else if (code == CODE_START) { btn = BTN_START; id = BTN_ID_START; - } - else if (code == CODE_SELECT) - { + } else if (code == CODE_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; - } - else if (code == CODE_MENU) - { + } else if (code == CODE_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; - } - else if (code == CODE_MENU_ALT) - { + } else if (code == CODE_MENU_ALT) { btn = BTN_MENU; id = BTN_ID_MENU; - } - else if (code == CODE_L1) - { + } else if (code == CODE_L1) { btn = BTN_L1; id = BTN_ID_L1; - } - else if (code == CODE_L2) - { + } else if (code == CODE_L2) { btn = BTN_L2; id = BTN_ID_L2; - } - else if (code == CODE_L3) - { + } else if (code == CODE_L3) { btn = BTN_L3; id = BTN_ID_L3; - } - else if (code == CODE_R1) - { + } else if (code == CODE_R1) { btn = BTN_R1; id = BTN_ID_R1; - } - else if (code == CODE_R2) - { + } else if (code == CODE_R2) { btn = BTN_R2; id = BTN_ID_R2; - } - else if (code == CODE_R3) - { + } else if (code == CODE_R3) { btn = BTN_R3; id = BTN_ID_R3; - } - else if (code == CODE_PLUS) - { + } else if (code == CODE_PLUS) { btn = BTN_PLUS; id = BTN_ID_PLUS; - } - else if (code == CODE_MINUS) - { + } else if (code == CODE_MINUS) { btn = BTN_MINUS; id = BTN_ID_MINUS; - } - else if (code == CODE_POWER) - { + } else if (code == CODE_POWER) { btn = BTN_POWER; id = BTN_ID_POWER; - } - else if (code == CODE_POWEROFF) - { + } else if (code == CODE_POWEROFF) { btn = BTN_POWEROFF; id = BTN_ID_POWEROFF; } // nano-only - } - else if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) - { + } else if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) { uint8_t joy = event.jbutton.button; pressed = event.type == SDL_JOYBUTTONDOWN; // LOG_info("joy event: %i (%i)\n", joy,pressed); - if (joy == JOY_UP) - { + if (joy == JOY_UP) { btn = BTN_DPAD_UP; id = BTN_ID_DPAD_UP; - } - else if (joy == JOY_DOWN) - { + } else if (joy == JOY_DOWN) { btn = BTN_DPAD_DOWN; id = BTN_ID_DPAD_DOWN; - } - else if (joy == JOY_LEFT) - { + } else if (joy == JOY_LEFT) { btn = BTN_DPAD_LEFT; id = BTN_ID_DPAD_LEFT; - } - else if (joy == JOY_RIGHT) - { + } else if (joy == JOY_RIGHT) { btn = BTN_DPAD_RIGHT; id = BTN_ID_DPAD_RIGHT; - } - else if (joy == JOY_A) - { + } else if (joy == JOY_A) { btn = BTN_A; id = BTN_ID_A; - } - else if (joy == JOY_B) - { + } else if (joy == JOY_B) { btn = BTN_B; id = BTN_ID_B; - } - else if (joy == JOY_X) - { + } else if (joy == JOY_X) { btn = BTN_X; id = BTN_ID_X; - } - else if (joy == JOY_Y) - { + } else if (joy == JOY_Y) { btn = BTN_Y; id = BTN_ID_Y; - } - else if (joy == JOY_START) - { + } else if (joy == JOY_START) { btn = BTN_START; id = BTN_ID_START; - } - else if (joy == JOY_SELECT) - { + } else if (joy == JOY_SELECT) { btn = BTN_SELECT; id = BTN_ID_SELECT; - } - else if (joy == JOY_MENU) - { + } else if (joy == JOY_MENU) { btn = BTN_MENU; id = BTN_ID_MENU; - } - else if (joy == JOY_MENU_ALT) - { + } else if (joy == JOY_MENU_ALT) { btn = BTN_MENU; id = BTN_ID_MENU; - } - else if (joy == JOY_MENU_ALT2) - { + } else if (joy == JOY_MENU_ALT2) { btn = BTN_MENU; id = BTN_ID_MENU; - } - else if (joy == JOY_L1) - { + } else if (joy == JOY_L1) { btn = BTN_L1; id = BTN_ID_L1; - } - else if (joy == JOY_L2) - { + } else if (joy == JOY_L2) { btn = BTN_L2; id = BTN_ID_L2; - } - else if (joy == JOY_L3) - { + } else if (joy == JOY_L3) { btn = BTN_L3; id = BTN_ID_L3; - } - else if (joy == JOY_R1) - { + } else if (joy == JOY_R1) { btn = BTN_R1; id = BTN_ID_R1; - } - else if (joy == JOY_R2) - { + } else if (joy == JOY_R2) { btn = BTN_R2; id = BTN_ID_R2; - } - else if (joy == JOY_R3) - { + } else if (joy == JOY_R3) { btn = BTN_R3; id = BTN_ID_R3; - } - else if (joy == JOY_PLUS) - { + } else if (joy == JOY_PLUS) { btn = BTN_PLUS; id = BTN_ID_PLUS; - } - else if (joy == JOY_MINUS) - { + } else if (joy == JOY_MINUS) { btn = BTN_MINUS; id = BTN_ID_MINUS; - } - else if (joy == JOY_POWER) - { + } else if (joy == JOY_POWER) { btn = BTN_POWER; id = BTN_ID_POWER; } - } - else if (event.type == SDL_JOYHATMOTION) - { + } else if (event.type == SDL_JOYHATMOTION) { int hats[4] = {-1, -1, -1, -1}; // -1=no change,0=up,1=down,2=left,3=right btn_ids int hat = event.jhat.value; // LOG_info("hat event: %i\n", hat); // TODO: safe to assume hats will always be the primary dpad? // TODO: this is literally a bitmask, make it one (oh, except there's 3 states...) - switch (hat) - { + switch (hat) { case SDL_HAT_UP: hats[0] = 1; hats[1] = 0; @@ -3125,18 +2800,14 @@ FALLBACK_IMPLEMENTATION void PLAT_pollInput(void) break; } - for (id = 0; id < 4; id++) - { + for (id = 0; id < 4; id++) { int state = hats[id]; btn = 1 << id; - if (state == 0) - { + if (state == 0) { pad.is_pressed &= ~btn; // unset pad.just_repeated &= ~btn; // unset pad.just_released |= btn; // set - } - else if (state == 1 && (pad.is_pressed & btn) == BTN_NONE) - { + } else if (state == 1 && (pad.is_pressed & btn) == BTN_NONE) { pad.just_pressed |= btn; // set pad.just_repeated |= btn; // set pad.is_pressed |= btn; // set @@ -3144,38 +2815,29 @@ FALLBACK_IMPLEMENTATION void PLAT_pollInput(void) } } btn = BTN_NONE; // already handled, force continue - } - else if (event.type == SDL_JOYAXISMOTION) - { + } else if (event.type == SDL_JOYAXISMOTION) { int axis = event.jaxis.axis; int val = event.jaxis.value; // LOG_info("axis: %i (%i)\n", axis,val); // triggers on tg5040 - if (axis == AXIS_L2) - { + if (axis == AXIS_L2) { btn = BTN_L2; id = BTN_ID_L2; pressed = val > 0; - } - else if (axis == AXIS_R2) - { + } else if (axis == AXIS_R2) { btn = BTN_R2; id = BTN_ID_R2; pressed = val > 0; } - else if (axis == AXIS_LX) - { + else if (axis == AXIS_LX) { pad.laxis.x = val; PAD_setAnalog(BTN_ID_ANALOG_LEFT, BTN_ID_ANALOG_RIGHT, val, tick + PAD_REPEAT_DELAY); - } - else if (axis == AXIS_LY) - { + } else if (axis == AXIS_LY) { pad.laxis.y = val; PAD_setAnalog(BTN_ID_ANALOG_UP, BTN_ID_ANALOG_DOWN, val, tick + PAD_REPEAT_DELAY); - } - else if (axis == AXIS_RX) + } else if (axis == AXIS_RX) pad.raxis.x = val; else if (axis == AXIS_RY) pad.raxis.y = val; @@ -3183,32 +2845,24 @@ FALLBACK_IMPLEMENTATION void PLAT_pollInput(void) // axis will fire off what looks like a release // before the first press but you can't release // a button that wasn't pressed - if (!pressed && btn != BTN_NONE && !(pad.is_pressed & btn)) - { + if (!pressed && btn != BTN_NONE && !(pad.is_pressed & btn)) { // LOG_info("cancel: %i\n", axis); btn = BTN_NONE; } - } - else if (event.type == SDL_QUIT) - { + } else if (event.type == SDL_QUIT) { PWR_powerOff(0); - } - else if (event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED) - { + } else if (event.type == SDL_JOYDEVICEADDED || event.type == SDL_JOYDEVICEREMOVED) { PAD_update(&event); } if (btn == BTN_NONE) continue; - if (!pressed) - { + if (!pressed) { pad.is_pressed &= ~btn; // unset pad.just_repeated &= ~btn; // unset pad.just_released |= btn; // set - } - else if ((pad.is_pressed & btn) == BTN_NONE) - { + } else if ((pad.is_pressed & btn) == BTN_NONE) { pad.just_pressed |= btn; // set pad.just_repeated |= btn; // set pad.is_pressed |= btn; // set @@ -3226,24 +2880,20 @@ FALLBACK_IMPLEMENTATION int PLAT_shouldWake(void) return 1; SDL_Event event; - while (SDL_PollEvent(&event)) - { - if (event.type == SDL_KEYUP) - { + while (SDL_PollEvent(&event)) { + if (event.type == SDL_KEYUP) { uint8_t code = event.key.keysym.scancode; - if ((BTN_WAKE == BTN_POWER && code == CODE_POWER) || (BTN_WAKE == BTN_MENU && (code == CODE_MENU || code == CODE_MENU_ALT))) - { + if ((BTN_WAKE == BTN_POWER && code == CODE_POWER) || + (BTN_WAKE == BTN_MENU && (code == CODE_MENU || code == CODE_MENU_ALT))) { // ignore input while lid is closed if (lid.has_lid && !lid.is_open) return 0; // do it here so we eat the input return 1; } - } - else if (event.type == SDL_JOYBUTTONUP) - { + } else if (event.type == SDL_JOYBUTTONUP) { uint8_t joy = event.jbutton.button; - if ((BTN_WAKE == BTN_POWER && joy == JOY_POWER) || (BTN_WAKE == BTN_MENU && (joy == JOY_MENU || joy == JOY_MENU_ALT))) - { + if ((BTN_WAKE == BTN_POWER && joy == JOY_POWER) || + (BTN_WAKE == BTN_MENU && (joy == JOY_MENU || joy == JOY_MENU_ALT))) { // ignore input while lid is closed if (lid.has_lid && !lid.is_open) return 0; // do it here so we eat the input @@ -3253,22 +2903,23 @@ FALLBACK_IMPLEMENTATION int PLAT_shouldWake(void) } return 0; } -FALLBACK_IMPLEMENTATION int PLAT_supportsDeepSleep(void) { return 0; } +FALLBACK_IMPLEMENTATION int PLAT_supportsDeepSleep(void) +{ + return 0; +} FALLBACK_IMPLEMENTATION int PLAT_deepSleep(void) { const char *state_path = "/sys/power/state"; int state_fd = open(state_path, O_WRONLY); - if (state_fd < 0) - { + if (state_fd < 0) { LOG_error("failed to open %s: %d\n", state_path, errno); return -1; } LOG_info("suspending to RAM\n"); int ret = write(state_fd, "mem", 3); - if (ret < 0) - { + if (ret < 0) { // Can fail shortly after resuming with EBUSY LOG_error("failed to set power state: %d\n", errno); close(state_fd); @@ -3280,27 +2931,46 @@ FALLBACK_IMPLEMENTATION int PLAT_deepSleep(void) return 0; } -int PAD_anyJustPressed(void) { return pad.just_pressed != BTN_NONE; } -int PAD_anyPressed(void) { return pad.is_pressed != BTN_NONE; } -int PAD_anyJustReleased(void) { return pad.just_released != BTN_NONE; } +int PAD_anyJustPressed(void) +{ + return pad.just_pressed != BTN_NONE; +} +int PAD_anyPressed(void) +{ + return pad.is_pressed != BTN_NONE; +} +int PAD_anyJustReleased(void) +{ + return pad.just_released != BTN_NONE; +} -int PAD_justPressed(int btn) { return pad.just_pressed & btn; } -int PAD_isPressed(int btn) { return pad.is_pressed & btn; } -int PAD_justReleased(int btn) { return pad.just_released & btn; } -int PAD_justRepeated(int btn) { return pad.just_repeated & btn; } +int PAD_justPressed(int btn) +{ + return pad.just_pressed & btn; +} +int PAD_isPressed(int btn) +{ + return pad.is_pressed & btn; +} +int PAD_justReleased(int btn) +{ + return pad.just_released & btn; +} +int PAD_justRepeated(int btn) +{ + return pad.just_repeated & btn; +} int PAD_tappedBtn(int btn, uint32_t now) { #define MENU_DELAY 250 // also in PWR_update() static uint32_t menu_start = 0; static int ignore_menu = 0; - if (PAD_justPressed(btn)) - { + if (PAD_justPressed(btn)) { ignore_menu = 0; menu_start = now; - } - else if (PAD_isPressed(btn) && BTN_MOD_BRIGHTNESS == btn && (PAD_justPressed(BTN_MOD_PLUS) || PAD_justPressed(BTN_MOD_MINUS))) - { + } else if (PAD_isPressed(btn) && BTN_MOD_BRIGHTNESS == btn && + (PAD_justPressed(BTN_MOD_PLUS) || PAD_justPressed(BTN_MOD_MINUS))) { ignore_menu = 1; } return (!ignore_menu && PAD_justReleased(btn) && now - menu_start < MENU_DELAY); @@ -3317,8 +2987,7 @@ int PAD_tappedSelect(uint32_t now) } /////////////////////////////// -static struct VIB_Context -{ +static struct VIB_Context { int initialized; pthread_t pt; int queued_strength; @@ -3328,13 +2997,12 @@ static void *VIB_thread(void *arg) { #define DEFER_FRAMES 3 static int defer = 0; - while (1) - { + while (1) { SDL_Delay(17); - if (vib.queued_strength != vib.strength) - { - if (defer < DEFER_FRAMES && vib.queued_strength == 0) - { // minimize vacillation between 0 and some number (which this motor doesn't like) + if (vib.queued_strength != vib.strength) { + if (defer < DEFER_FRAMES && + vib.queued_strength == + 0) { // minimize vacillation between 0 and some number (which this motor doesn't like) defer += 1; continue; } @@ -3456,8 +3124,7 @@ void PWR_updateFrequency(int secs, int updateWifi) static void *PWR_monitorBattery(void *arg) { - while (1) - { + while (1) { struct PWR_Context *pwr_ctx = (struct PWR_Context *)arg; sleep(pwr_ctx->update_secs); PWR_updateBatteryStatus(); @@ -3529,41 +3196,35 @@ void PWR_update(int *_dirty, int *_show_setting, PWR_callback_t before_sleep, PW was_muted = GetMute(); static int was_charging = -1; - if (was_charging == -1) was_charging = pwr.is_charging; + if (was_charging == -1) + was_charging = pwr.is_charging; uint32_t now = SDL_GetTicks(); if (was_charging || PAD_anyPressed() || last_input_at == 0) last_input_at = now; #define CHARGE_DELAY 1000 - if (dirty || now - checked_charge_at >= CHARGE_DELAY) - { + if (dirty || now - checked_charge_at >= CHARGE_DELAY) { int is_charging = pwr.is_charging; - if (was_charging != is_charging) - { + if (was_charging != is_charging) { was_charging = is_charging; dirty = 1; } checked_charge_at = now; } - if (PAD_justReleased(BTN_POWEROFF) || (power_pressed_at && now - power_pressed_at >= 1000)) - { + if (PAD_justReleased(BTN_POWEROFF) || (power_pressed_at && now - power_pressed_at >= 1000)) { if (before_sleep) before_sleep(); system("gametimectl.elf stop_all"); PWR_powerOff(0); } - if (PAD_justPressed(BTN_POWER)) - { - if (now - pwr.resume_tick < 1000) - { + if (PAD_justPressed(BTN_POWER)) { + if (now - pwr.resume_tick < 1000) { LOG_debug("ignoring spurious power button press (just resumed)\n"); power_pressed_at = 0; - } - else - { + } else { power_pressed_at = now; } } @@ -3572,12 +3233,10 @@ void PWR_update(int *_dirty, int *_show_setting, PWR_callback_t before_sleep, PW if (screenOffDelay == 0 || (now - last_input_at >= screenOffDelay && PWR_preventAutosleep())) last_input_at = now; - if ( - pwr.requested_sleep || // hardware requested sleep + if (pwr.requested_sleep || // hardware requested sleep (screenOffDelay > 0 && now - last_input_at >= screenOffDelay) || // autosleep (pwr.can_sleep && PAD_justReleased(BTN_SLEEP) && power_pressed_at) // manual sleep - ) - { + ) { pwr.requested_sleep = 0; if (before_sleep) before_sleep(); @@ -3591,48 +3250,42 @@ void PWR_update(int *_dirty, int *_show_setting, PWR_callback_t before_sleep, PW int was_dirty = dirty; // dirty list (not including settings/battery) - // TODO: only delay hiding setting changes if that setting didn't require a modifier button be held, otherwise release as soon as modifier is released + // TODO: only delay hiding setting changes if that setting didn't require a modifier button be held, otherwise + // release as soon as modifier is released - int delay_settings = BTN_MOD_BRIGHTNESS == BTN_MENU; // when both volume and brighness require a modifier hide settings as soon as it is released + int delay_settings = + BTN_MOD_BRIGHTNESS == + BTN_MENU; // when both volume and brighness require a modifier hide settings as soon as it is released #define SETTING_DELAY 500 - if (show_setting && (now - setting_shown_at >= SETTING_DELAY || !delay_settings) && !PAD_isPressed(BTN_MOD_VOLUME) && !PAD_isPressed(BTN_MOD_BRIGHTNESS) && !PAD_isPressed(BTN_MOD_COLORTEMP)) - { + if (show_setting && (now - setting_shown_at >= SETTING_DELAY || !delay_settings) && + !PAD_isPressed(BTN_MOD_VOLUME) && !PAD_isPressed(BTN_MOD_BRIGHTNESS) && !PAD_isPressed(BTN_MOD_COLORTEMP)) { show_setting = 0; dirty = 1; } - if (!show_setting && !PAD_isPressed(BTN_MOD_VOLUME) && !PAD_isPressed(BTN_MOD_BRIGHTNESS) && !PAD_isPressed(BTN_MOD_COLORTEMP)) - { + if (!show_setting && !PAD_isPressed(BTN_MOD_VOLUME) && !PAD_isPressed(BTN_MOD_BRIGHTNESS) && + !PAD_isPressed(BTN_MOD_COLORTEMP)) { mod_unpressed_at = now; // this feels backwards but is correct } #define MOD_DELAY 250 - if ( - ( - (PAD_isPressed(BTN_MOD_VOLUME) || PAD_isPressed(BTN_MOD_BRIGHTNESS) || PAD_isPressed(BTN_MOD_COLORTEMP)) && - (!delay_settings || now - mod_unpressed_at >= MOD_DELAY)) || - ((!BTN_MOD_VOLUME || !BTN_MOD_BRIGHTNESS || !BTN_MOD_COLORTEMP) && (PAD_justRepeated(BTN_MOD_PLUS) || PAD_justRepeated(BTN_MOD_MINUS)))) - { + if (((PAD_isPressed(BTN_MOD_VOLUME) || PAD_isPressed(BTN_MOD_BRIGHTNESS) || PAD_isPressed(BTN_MOD_COLORTEMP)) && + (!delay_settings || now - mod_unpressed_at >= MOD_DELAY)) || + ((!BTN_MOD_VOLUME || !BTN_MOD_BRIGHTNESS || !BTN_MOD_COLORTEMP) && + (PAD_justRepeated(BTN_MOD_PLUS) || PAD_justRepeated(BTN_MOD_MINUS)))) { setting_shown_at = now; - if (PAD_isPressed(BTN_MOD_BRIGHTNESS)) - { + if (PAD_isPressed(BTN_MOD_BRIGHTNESS)) { show_setting = 1; - } - else if (PAD_isPressed(BTN_MOD_COLORTEMP)) - { + } else if (PAD_isPressed(BTN_MOD_COLORTEMP)) { show_setting = 3; - } - else - { + } else { show_setting = 2; } } - if (InitializedSettings()) - { + if (InitializedSettings()) { int muted = GetMute(); - if (muted != was_muted) - { + if (muted != was_muted) { was_muted = muted; show_setting = 2; setting_shown_at = now; @@ -3665,14 +3318,11 @@ void PWR_disablePowerOff(void) } void PWR_powerOff(int reboot) { - if (pwr.can_poweroff) - { - + if (pwr.can_poweroff) { int w = FIXED_WIDTH; int h = FIXED_HEIGHT; int p = FIXED_PITCH; - if (GetHDMI()) - { + if (GetHDMI()) { w = HDMI_WIDTH; h = HDMI_HEIGHT; p = HDMI_PITCH; @@ -3680,17 +3330,14 @@ void PWR_powerOff(int reboot) gfx.screen = GFX_resize(w, h, p); char *msg; - if (HAS_POWER_BUTTON || HAS_POWEROFF_BUTTON) - { + if (HAS_POWER_BUTTON || HAS_POWEROFF_BUTTON) { if (exists(AUTO_RESUME_PATH)) msg = (char *)"Quicksave created,\npowering off"; else if (reboot > 0) msg = (char *)"Rebooting"; else msg = (char *)"Powering off"; - } - else - { + } else { msg = exists(AUTO_RESUME_PATH) ? (char *)"Quicksave created,\npower off now" : (char *)"Power off now"; } @@ -3718,16 +3365,12 @@ static void PWR_enterSleep(void) { SND_pauseAudio(true); LEDS_pushProfileOverride(LIGHT_PROFILE_SLEEP); - if (GetHDMI()) - { + if (GetHDMI()) { PLAT_clearVideo(gfx.screen); PLAT_flip(gfx.screen, 0); - } - else - { + } else { SetRawVolume(MUTE_VOLUME_RAW); - if (CFG_getHaptics()) - { + if (CFG_getHaptics()) { VIB_singlePulse(VIB_sleepStrength, VIB_sleepDuration_ms); } PLAT_enableBacklight(0); @@ -3754,14 +3397,10 @@ static void PWR_exitSleep(void) // system("killall -CONT wifi_daemon"); system("killall -CONT audiomon.elf"); - if (GetHDMI()) - { + if (GetHDMI()) { // buh - } - else - { - if (CFG_getHaptics()) - { + } else { + if (CFG_getHaptics()) { VIB_singlePulse(VIB_sleepStrength, VIB_sleepDuration_ms); } PLAT_enableBacklight(1); @@ -3779,44 +3418,32 @@ static void PWR_waitForWake(void) uint32_t sleep_ticks = SDL_GetTicks(); int deep_sleep_attempts = 0; const int sleepDelay = CFG_getSuspendTimeoutSecs() * 1000; - while (!PAD_wake()) - { - if (pwr.requested_wake) - { + while (!PAD_wake()) { + if (pwr.requested_wake) { pwr.requested_wake = 0; break; } - if (sleepDelay > 0) - { + if (sleepDelay > 0) { SDL_Delay(200); - if (SDL_GetTicks() - sleep_ticks >= sleepDelay) - { // increased to two minutes - if (pwr.is_charging) - { + if (SDL_GetTicks() - sleep_ticks >= sleepDelay) { // increased to two minutes + if (pwr.is_charging) { sleep_ticks += 60000; // check again in a minute continue; } - if (PLAT_supportsDeepSleep()) - { + if (PLAT_supportsDeepSleep()) { int ret = PWR_deepSleep(); - if (ret == 0) - { + if (ret == 0) { return; - } - else if (deep_sleep_attempts < 3) - { + } else if (deep_sleep_attempts < 3) { LOG_warn("failed to enter deep sleep - retrying in 5 seconds\n"); sleep_ticks += 5000; deep_sleep_attempts++; continue; - } - else - { + } else { LOG_warn("failed to enter deep sleep - powering off\n"); } } - if (pwr.can_poweroff) - { + if (pwr.can_poweroff) { PWR_powerOff(0); } } @@ -3851,13 +3478,11 @@ int PWR_deepSleep(void) // We assume the suspend executable exits after a full // suspend/resume cycle. char *suspend_path = BIN_PATH "/suspend"; - if (exists(suspend_path)) - { + if (exists(suspend_path)) { LOG_info("suspending using platform suspend executable\n"); int ret = system(suspend_path); - if (ret < 0) - { + if (ret < 0) { LOG_error("failed to launch suspend executable: %d\n", errno); return -1; } @@ -3906,70 +3531,83 @@ FALLBACK_IMPLEMENTATION int PLAT_setDateTime(int y, int m, int d, int h, int i, /////////////////////////////// // RGB LED cruft -FALLBACK_IMPLEMENTATION void PLAT_initLeds(LightSettings *lights) {} -FALLBACK_IMPLEMENTATION void PLAT_setLedBrightness(LightSettings *led) {} -FALLBACK_IMPLEMENTATION void PLAT_setLedEffect(LightSettings *led) {} -FALLBACK_IMPLEMENTATION void PLAT_setLedColor(LightSettings *led) {} -FALLBACK_IMPLEMENTATION void PLAT_setLedInbrightness(LightSettings *led) {} -FALLBACK_IMPLEMENTATION void PLAT_setLedEffectCycles(LightSettings *led) {} -FALLBACK_IMPLEMENTATION void PLAT_setLedEffectSpeed(LightSettings *led) {} +FALLBACK_IMPLEMENTATION void PLAT_initLeds(LightSettings *lights) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_setLedBrightness(LightSettings *led) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_setLedEffect(LightSettings *led) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_setLedColor(LightSettings *led) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_setLedInbrightness(LightSettings *led) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_setLedEffectCycles(LightSettings *led) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_setLedEffectSpeed(LightSettings *led) +{ +} void LEDS_setProfile(int profile) { - if(lights_initialized == 0) + if (lights_initialized == 0) return; LightSettings *new_lights = NULL; bool indicator = true; - switch(profile) - { - case LIGHT_PROFILE_DEFAULT: - new_lights = lightsDefault; - indicator = false; - break; - case LIGHT_PROFILE_OFF: - new_lights = lightsOff; - indicator = false; - break; - case LIGHT_PROFILE_LOW_BATTERY: - new_lights = lightsLowBattery; - break; - case LIGHT_PROFILE_CRITICAL_BATTERY: - new_lights = lightsCriticalBattery; - break; - case LIGHT_PROFILE_CHARGING: - new_lights = lightsCharging; - break; - case LIGHT_PROFILE_SLEEP: - new_lights = lightsSleep; - break; - case LIGHT_PROFILE_AMBIENT: - new_lights = lightsAmbient; - indicator = false; - break; - default: - return; + switch (profile) { + case LIGHT_PROFILE_DEFAULT: + new_lights = lightsDefault; + indicator = false; + break; + case LIGHT_PROFILE_OFF: + new_lights = lightsOff; + indicator = false; + break; + case LIGHT_PROFILE_LOW_BATTERY: + new_lights = lightsLowBattery; + break; + case LIGHT_PROFILE_CRITICAL_BATTERY: + new_lights = lightsCriticalBattery; + break; + case LIGHT_PROFILE_CHARGING: + new_lights = lightsCharging; + break; + case LIGHT_PROFILE_SLEEP: + new_lights = lightsSleep; + break; + case LIGHT_PROFILE_AMBIENT: + new_lights = lightsAmbient; + indicator = false; + break; + default: + return; } - if (profile != LIGHT_PROFILE_AMBIENT && lights == (LightSettings (*)[MAX_LIGHTS])new_lights) + if (profile != LIGHT_PROFILE_AMBIENT && lights == (LightSettings(*)[MAX_LIGHTS])new_lights) return; - lights = (LightSettings (*)[MAX_LIGHTS])new_lights; + lights = (LightSettings(*)[MAX_LIGHTS])new_lights; LEDS_updateLeds(indicator); } void LEDS_applyRules() { - if(lights_initialized == 0) { + if (lights_initialized == 0) { LOG_error("LEDS_applyRules: lights not initialized, skipping\n"); return; } - + // some rules rely on pwr.is_charging and pwr.charge being valid - if(pwr.initialized == 0) + if (pwr.initialized == 0) LOG_warn("LEDS_applyRules called before PWR_init\n"); // some rules rely in InitSettings() being called (e.g GetMute()) - if(!InitializedSettings()) + if (!InitializedSettings()) LOG_warn("LEDS_applyRules called before InitSettings\n"); // these are defined in order of priority, not necessarily in the order @@ -3977,53 +3615,51 @@ void LEDS_applyRules() // e.g. // - if charging and low battery, charging takes priority if (pwr.initialized && pwr.is_charging) { - //LOG_info("LEDS_applyRules: charging\n"); + // LOG_info("LEDS_applyRules: charging\n"); LEDS_setProfile(LIGHT_PROFILE_CHARGING); } // - if critical battery, critical battery takes priority over everything else if (pwr.initialized && pwr.charge < PWR_LOW_CHARGE) { - //LOG_info("LEDS_applyRules: critical battery\n"); + // LOG_info("LEDS_applyRules: critical battery\n"); LEDS_setProfile(LIGHT_PROFILE_CRITICAL_BATTERY); } // - if muted, muted takes priority over everything except critical battery - else if(InitializedSettings() && CFG_getMuteLEDs() && GetMute()) { - //LOG_info("LEDS_applyRules: muted\n"); + else if (InitializedSettings() && CFG_getMuteLEDs() && GetMute()) { + // LOG_info("LEDS_applyRules: muted\n"); LEDS_setProfile(LIGHT_PROFILE_OFF); } // other rules else if (pwr.initialized && pwr.charge < PWR_LOW_CHARGE + 10 && pwr.charge >= PWR_LOW_CHARGE) { - //LOG_info("LEDS_applyRules: low battery\n"); + // LOG_info("LEDS_applyRules: low battery\n"); LEDS_setProfile(LIGHT_PROFILE_LOW_BATTERY); } // - if no other rule applies, use default (or temporary override) // manual rules to be set on demand: LIGHT_PROFILE_SLEEP, LIGHT_PROFILE_AMBIENT else { - //LOG_info("LEDS_applyRules: default/override: %i\n", LEDS_getProfileOverride()); + // LOG_info("LEDS_applyRules: default/override: %i\n", LEDS_getProfileOverride()); LEDS_setProfile(LEDS_getProfileOverride()); } } void LEDS_updateLeds(bool indicator_only) { - if(lights_initialized == 0) { + if (lights_initialized == 0) { LOG_error("LEDS_updateLeds: lights not initialized, skipping\n"); return; } - + int lightsize = 3; char *device = getenv("DEVICE"); int is_brick = exactMatch("brick", device); if (is_brick) lightsize = 4; - if(!lights) - { + if (!lights) { LOG_error("LEDS_updateLeds called but lights is NULL\n"); return; } - for (int i = 0; i < lightsize; i++) - { + for (int i = 0; i < lightsize; i++) { // set brightness of each led - if(indicator_only) + if (indicator_only) PLAT_setLedInbrightness(&(*lights)[i]); else PLAT_setLedBrightness(&(*lights)[i]); @@ -4031,7 +3667,7 @@ void LEDS_updateLeds(bool indicator_only) PLAT_setLedEffectCycles(&(*lights)[i]); // set how many times animation should loop PLAT_setLedEffectSpeed(&(*lights)[i]); // set animation speed PLAT_setLedColor(&(*lights)[i]); // set color - PLAT_setLedEffect(&(*lights)[i]); // finally set the effect, on trimui devices this also applies the settings + PLAT_setLedEffect(&(*lights)[i]); // finally set the effect, on trimui devices this also applies the settings } } @@ -4039,15 +3675,13 @@ void LEDS_initLeds() { PLAT_initLeds(lightsDefault); - if(!lightsDefault) - { + if (!lightsDefault) { LOG_error("LEDS_initLeds called but lightsDefault is NULL\n"); return; } int lightsize = sizeof(lightsDefault) / sizeof(LightSettings); - for (int i = 0; i < lightsize; i++) - { + for (int i = 0; i < lightsize; i++) { // LIGHT_PROFILE_OFF lightsOff[i] = lightsDefault[i]; lightsOff[i].brightness = 0; @@ -4069,7 +3703,7 @@ void LEDS_initLeds() lightsCharging[i] = lightsDefault[i]; lightsCharging[i].effect = 2; // breathe lightsCharging[i].color1 = 0x00FF00; - lightsCharging[i].cycles = -1; // infinite + lightsCharging[i].cycles = -1; // infinite // LIGHT_PROFILE_SLEEP lightsSleep[i] = lightsDefault[i]; @@ -4092,8 +3726,7 @@ void LEDS_initLeds() bool LEDS_pushProfileOverride(int profile) { - if(profile_override_top == PROFILE_OVERRIDE_SIZE - 1) - { + if (profile_override_top == PROFILE_OVERRIDE_SIZE - 1) { LOG_debug("LED_profile stack is full, ignoring.\n"); return false; } @@ -4105,12 +3738,13 @@ bool LEDS_pushProfileOverride(int profile) bool LEDS_popProfileOverride(int profile) { - if(profile_override_top == -1) { + if (profile_override_top == -1) { LOG_debug("LED_profile stack is empty, nothing to pop.\n"); return false; } - if(LEDS_getProfileOverride() != profile) { - LOG_debug("LEDS_popProfileOverride attempted to remove %d, but top of stack is %d\n", profile, LEDS_getProfileOverride()); + if (LEDS_getProfileOverride() != profile) { + LOG_debug("LEDS_popProfileOverride attempted to remove %d, but top of stack is %d\n", profile, + LEDS_getProfileOverride()); return false; } profile_override_top--; @@ -4122,21 +3756,31 @@ bool LEDS_popProfileOverride(int profile) // returns top of stack, or default if stack is empty int LEDS_getProfileOverride() { - if(profile_override_top == -1) { + if (profile_override_top == -1) { LOG_debug("LED_profile stack is empty, returning default profile.\n"); return LIGHT_PROFILE_DEFAULT; } - + LOG_info("LEDS_getProfileOverride: %i\n", profile_override[profile_override_top]); return profile_override[profile_override_top]; } ///////////////////////////////////////////////////////////////////////////////////////// -FALLBACK_IMPLEMENTATION bool PLAT_canTurbo(void) { return false; } -FALLBACK_IMPLEMENTATION int PLAT_toggleTurbo(int btn_id) { return 0; } -FALLBACK_IMPLEMENTATION void PLAT_clearTurbo() {} -FALLBACK_IMPLEMENTATION void PLAT_updateInput(const SDL_Event *event) {} +FALLBACK_IMPLEMENTATION bool PLAT_canTurbo(void) +{ + return false; +} +FALLBACK_IMPLEMENTATION int PLAT_toggleTurbo(int btn_id) +{ + return 0; +} +FALLBACK_IMPLEMENTATION void PLAT_clearTurbo() +{ +} +FALLBACK_IMPLEMENTATION void PLAT_updateInput(const SDL_Event *event) +{ +} ///////////////////////////////////////////////////////////////////////////////////////// @@ -4146,8 +3790,7 @@ FALLBACK_IMPLEMENTATION FILE *PLAT_OpenSettings(const char *filename) snprintf(diskfilename, sizeof(diskfilename), SHARED_USERDATA_PATH "/%s", filename); FILE *file = fopen(diskfilename, "r"); - if (file == NULL) - { + if (file == NULL) { return NULL; } return file; @@ -4159,61 +3802,165 @@ FALLBACK_IMPLEMENTATION FILE *PLAT_WriteSettings(const char *filename) snprintf(diskfilename, sizeof(diskfilename), SHARED_USERDATA_PATH "/%s", filename); FILE *file = fopen(diskfilename, "w"); - if (file == NULL) - { + if (file == NULL) { return NULL; } return file; } ///////////////////////////////////////////////////////////////////////////////////////// -FALLBACK_IMPLEMENTATION void PLAT_initTimezones() {} -FALLBACK_IMPLEMENTATION void PLAT_getTimezones(char timezones[MAX_TIMEZONES][MAX_TZ_LENGTH], int *tz_count) { tz_count = 0; } -FALLBACK_IMPLEMENTATION char *PLAT_getCurrentTimezone() { return "Foo/Bar"; } -FALLBACK_IMPLEMENTATION void PLAT_setCurrentTimezone(const char *tz) {} -FALLBACK_IMPLEMENTATION bool PLAT_getNetworkTimeSync(void) { return true; } -FALLBACK_IMPLEMENTATION void PLAT_setNetworkTimeSync(bool on) {} +FALLBACK_IMPLEMENTATION void PLAT_initTimezones() +{ +} +FALLBACK_IMPLEMENTATION void PLAT_getTimezones(char timezones[MAX_TIMEZONES][MAX_TZ_LENGTH], int *tz_count) +{ + tz_count = 0; +} +FALLBACK_IMPLEMENTATION char *PLAT_getCurrentTimezone() +{ + return "Foo/Bar"; +} +FALLBACK_IMPLEMENTATION void PLAT_setCurrentTimezone(const char *tz) +{ +} +FALLBACK_IMPLEMENTATION bool PLAT_getNetworkTimeSync(void) +{ + return true; +} +FALLBACK_IMPLEMENTATION void PLAT_setNetworkTimeSync(bool on) +{ +} ///////////////////////////////////////////////////////////////////////////////////////// -FALLBACK_IMPLEMENTATION void PLAT_wifiInit() {} -FALLBACK_IMPLEMENTATION bool PLAT_hasWifi() { return false; } -FALLBACK_IMPLEMENTATION bool PLAT_wifiEnabled() { return false; } -FALLBACK_IMPLEMENTATION void PLAT_wifiEnable(bool on) {} - -FALLBACK_IMPLEMENTATION int PLAT_wifiScan(struct WIFI_network *networks, int max) { return 0; } -FALLBACK_IMPLEMENTATION bool PLAT_wifiConnected() { return false; } -FALLBACK_IMPLEMENTATION int PLAT_wifiConnection(struct WIFI_connection *connection_info) { return 0; } -FALLBACK_IMPLEMENTATION bool PLAT_wifiHasCredentials(char *ssid, WifiSecurityType sec) { return false; } -FALLBACK_IMPLEMENTATION void PLAT_wifiForget(char *ssid, WifiSecurityType sec) {} -FALLBACK_IMPLEMENTATION void PLAT_wifiConnect(char *ssid, WifiSecurityType sec) {} -FALLBACK_IMPLEMENTATION void PLAT_wifiConnectPass(const char *ssid, WifiSecurityType sec, const char *pass) {} -FALLBACK_IMPLEMENTATION void PLAT_wifiDisconnect() {} -FALLBACK_IMPLEMENTATION bool PLAT_wifiDiagnosticsEnabled() { return false; } -FALLBACK_IMPLEMENTATION void PLAT_wifiDiagnosticsEnable(bool on) {} +FALLBACK_IMPLEMENTATION void PLAT_wifiInit() +{ +} +FALLBACK_IMPLEMENTATION bool PLAT_hasWifi() +{ + return false; +} +FALLBACK_IMPLEMENTATION bool PLAT_wifiEnabled() +{ + return false; +} +FALLBACK_IMPLEMENTATION void PLAT_wifiEnable(bool on) +{ +} + +FALLBACK_IMPLEMENTATION int PLAT_wifiScan(struct WIFI_network *networks, int max) +{ + return 0; +} +FALLBACK_IMPLEMENTATION bool PLAT_wifiConnected() +{ + return false; +} +FALLBACK_IMPLEMENTATION int PLAT_wifiConnection(struct WIFI_connection *connection_info) +{ + return 0; +} +FALLBACK_IMPLEMENTATION bool PLAT_wifiHasCredentials(char *ssid, WifiSecurityType sec) +{ + return false; +} +FALLBACK_IMPLEMENTATION void PLAT_wifiForget(char *ssid, WifiSecurityType sec) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_wifiConnect(char *ssid, WifiSecurityType sec) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_wifiConnectPass(const char *ssid, WifiSecurityType sec, const char *pass) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_wifiDisconnect() +{ +} +FALLBACK_IMPLEMENTATION bool PLAT_wifiDiagnosticsEnabled() +{ + return false; +} +FALLBACK_IMPLEMENTATION void PLAT_wifiDiagnosticsEnable(bool on) +{ +} ///////////////////////////////////////////////////////////////////////////////////////// -FALLBACK_IMPLEMENTATION void PLAT_bluetoothInit() {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothDeinit() {} -FALLBACK_IMPLEMENTATION bool PLAT_hasBluetooth() { return false; } -FALLBACK_IMPLEMENTATION bool PLAT_bluetoothEnabled() { return false; } -FALLBACK_IMPLEMENTATION void PLAT_bluetoothEnable(bool on) {} -FALLBACK_IMPLEMENTATION bool PLAT_bluetoothDiagnosticsEnabled() { return false; } -FALLBACK_IMPLEMENTATION void PLAT_bluetoothDiagnosticsEnable(bool on) {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothDiscovery(int on) {} -FALLBACK_IMPLEMENTATION bool PLAT_bluetoothDiscovering() { return false; } -FALLBACK_IMPLEMENTATION int PLAT_bluetoothScan(struct BT_device *devices, int max) { return 0; } -FALLBACK_IMPLEMENTATION int PLAT_bluetoothPaired(struct BT_devicePaired *devices, int max) { return 0; } -FALLBACK_IMPLEMENTATION void PLAT_bluetoothPair(char *addr) {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothUnpair(char *addr) {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothConnect(char *addr) {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothDisconnect(char *addr) {} -FALLBACK_IMPLEMENTATION bool PLAT_bluetoothConnected() { return false; } -FALLBACK_IMPLEMENTATION bool PLAT_btIsConnected(void) { return PLAT_bluetoothConnected(); } -FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamInit(int ch, int samplerate) {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamBegin(int buffersize) {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamEnd() {} -FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamQuit() {} -FALLBACK_IMPLEMENTATION int PLAT_bluetoothVolume() { return 100; } -FALLBACK_IMPLEMENTATION void PLAT_bluetoothSetVolume(int vol) {} \ No newline at end of file +FALLBACK_IMPLEMENTATION void PLAT_bluetoothInit() +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothDeinit() +{ +} +FALLBACK_IMPLEMENTATION bool PLAT_hasBluetooth() +{ + return false; +} +FALLBACK_IMPLEMENTATION bool PLAT_bluetoothEnabled() +{ + return false; +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothEnable(bool on) +{ +} +FALLBACK_IMPLEMENTATION bool PLAT_bluetoothDiagnosticsEnabled() +{ + return false; +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothDiagnosticsEnable(bool on) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothDiscovery(int on) +{ +} +FALLBACK_IMPLEMENTATION bool PLAT_bluetoothDiscovering() +{ + return false; +} +FALLBACK_IMPLEMENTATION int PLAT_bluetoothScan(struct BT_device *devices, int max) +{ + return 0; +} +FALLBACK_IMPLEMENTATION int PLAT_bluetoothPaired(struct BT_devicePaired *devices, int max) +{ + return 0; +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothPair(char *addr) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothUnpair(char *addr) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothConnect(char *addr) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothDisconnect(char *addr) +{ +} +FALLBACK_IMPLEMENTATION bool PLAT_bluetoothConnected() +{ + return false; +} +FALLBACK_IMPLEMENTATION bool PLAT_btIsConnected(void) +{ + return PLAT_bluetoothConnected(); +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamInit(int ch, int samplerate) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamBegin(int buffersize) +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamEnd() +{ +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothStreamQuit() +{ +} +FALLBACK_IMPLEMENTATION int PLAT_bluetoothVolume() +{ + return 100; +} +FALLBACK_IMPLEMENTATION void PLAT_bluetoothSetVolume(int vol) +{ +} \ No newline at end of file diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index 15a7a0b23..4f4bac7a8 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -19,33 +19,33 @@ enum { #define LOG_info(fmt, ...) LOG_note(LOG_INFO, fmt, ##__VA_ARGS__) #define LOG_warn(fmt, ...) LOG_note(LOG_WARN, fmt, ##__VA_ARGS__) #define LOG_error(fmt, ...) LOG_note(LOG_ERROR, fmt, ##__VA_ARGS__) -void LOG_note(int level, const char* fmt, ...); +void LOG_note(int level, const char *fmt, ...); /////////////////////////////// -#define PAGE_COUNT 2 -#define PAGE_SCALE 3 -#define PAGE_WIDTH (FIXED_WIDTH * PAGE_SCALE) -#define PAGE_HEIGHT (FIXED_HEIGHT * PAGE_SCALE) -#define PAGE_PITCH (PAGE_WIDTH * FIXED_BPP) -#define PAGE_SIZE (PAGE_PITCH * PAGE_HEIGHT) +#define PAGE_COUNT 2 +#define PAGE_SCALE 3 +#define PAGE_WIDTH (FIXED_WIDTH * PAGE_SCALE) +#define PAGE_HEIGHT (FIXED_HEIGHT * PAGE_SCALE) +#define PAGE_PITCH (PAGE_WIDTH * FIXED_BPP) +#define PAGE_SIZE (PAGE_PITCH * PAGE_HEIGHT) /////////////////////////////// // TODO: these only seem to be used by a tmp.pak in trimui (model s) // used by minarch, optionally defined in platform.h #ifndef PLAT_PAGE_BPP -#define PLAT_PAGE_BPP FIXED_BPP +#define PLAT_PAGE_BPP FIXED_BPP #endif #define PLAT_PAGE_DEPTH (PLAT_PAGE_BPP * 8) #define PLAT_PAGE_PITCH (PAGE_WIDTH * PLAT_PAGE_BPP) -#define PLAT_PAGE_SIZE (PLAT_PAGE_PITCH * PAGE_HEIGHT) +#define PLAT_PAGE_SIZE (PLAT_PAGE_PITCH * PAGE_HEIGHT) /////////////////////////////// -#define RGBA_MASK_AUTO 0x0, 0x0, 0x0, 0x0 -#define RGBA_MASK_565 0xF800, 0x07E0, 0x001F, 0x0000 -#define RGBA_MASK_8888 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 +#define RGBA_MASK_AUTO 0x0, 0x0, 0x0, 0x0 +#define RGBA_MASK_565 0xF800, 0x07E0, 0x001F, 0x0000 +#define RGBA_MASK_8888 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 /////////////////////////////// @@ -118,9 +118,9 @@ enum { ASSET_UNDERLINE, ASSET_DOT, ASSET_HOLE, - + ASSET_COLORS, - + ASSET_BRIGHTNESS, ASSET_COLORTEMP, ASSET_VOLUME_MUTE, @@ -130,10 +130,10 @@ enum { ASSET_BATTERY_FILL, ASSET_BATTERY_FILL_LOW, ASSET_BATTERY_BOLT, - + ASSET_SCROLL_UP, ASSET_SCROLL_DOWN, - + ASSET_WIFI, ASSET_WIFI_MED, ASSET_WIFI_LOW, @@ -143,7 +143,7 @@ enum { ASSET_BLUETOOTH_OFF, ASSET_AUDIO, ASSET_CONTROLLER, - + ASSET_CHECKCIRCLE, ASSET_LOCK, ASSET_SETTINGS, @@ -152,16 +152,16 @@ enum { ASSET_POWEROFF, ASSET_RESTART, ASSET_SUSPEND, - + ASSET_COUNT, }; typedef struct GFX_Fonts { - TTF_Font* large; // menu - TTF_Font* medium; // single char button label - TTF_Font* small; // button hint - TTF_Font* tiny; // multi char button label - TTF_Font* micro; // icon overlay text + TTF_Font *large; // menu + TTF_Font *medium; // single char button label + TTF_Font *small; // button hint + TTF_Font *tiny; // multi char button label + TTF_Font *micro; // icon overlay text } GFX_Fonts; extern GFX_Fonts font; @@ -179,12 +179,12 @@ enum { }; typedef struct GFX_Renderer { - void* src; - void* dst; - void* blit; + void *src; + void *dst; + void *blit; double aspect; // 0 for integer, -1 for fullscreen, otherwise aspect ratio, used for SDL2 accelerated scaling int scale; - + // TODO: document this better int true_w; int true_h; @@ -194,7 +194,7 @@ typedef struct GFX_Renderer { int src_w; int src_h; int src_p; - + // TODO: I think this is overscaled int dst_x; int dst_y; @@ -203,20 +203,19 @@ typedef struct GFX_Renderer { int dst_p; } GFX_Renderer; -typedef struct -{ - char name[255]; - char filename[255]; - int effect; - int speed; - int brightness; - uint32_t color1; - uint32_t color2; - int updated; - int colorFrames[255]; - int trigger; - int inbrightness; - int cycles; +typedef struct { + char name[255]; + char filename[255]; + int effect; + int speed; + int brightness; + uint32_t color1; + uint32_t color2; + int updated; + int colorFrames[255]; + int trigger; + int inbrightness; + int cycles; } LightSettings; @@ -229,12 +228,12 @@ enum { #define MAX_PARAM_NAME 128 #define MAX_PARAM_LABEL 128 typedef struct { - char name[MAX_PARAM_NAME]; - char label[MAX_PARAM_LABEL]; - float def; - float min; - float max; - float step; + char name[MAX_PARAM_NAME]; + char label[MAX_PARAM_LABEL]; + float def; + float min; + float max; + float step; float value; GLint uniformLocation; } ShaderParam; @@ -248,39 +247,41 @@ enum { LAYER_IDK2 = 5, // unused? }; -SDL_Surface* GFX_init(int mode); -#define GFX_resize PLAT_resizeVideo // (int w, int h, int pitch); -#define GFX_setSharpness PLAT_setSharpness // (int sharpness) -#define GFX_setEffectColor PLAT_setEffectColor // (int color) -#define GFX_setEffect PLAT_setEffect // (int effect) -#define GFX_setOverlay PLAT_setOverlay// (int effect) -#define GFX_setOffsetX PLAT_setOffsetX// (int effect) -#define GFX_setOffsetY PLAT_setOffsetY// (int effect) -#define GFX_drawOnLayer PLAT_drawOnLayer //(SDL_Surface *inputSurface,int x, int y) -#define GFX_clearLayers PLAT_clearLayers //(SDL_Surface *inputSurface,int x, int y) +SDL_Surface *GFX_init(int mode); +#define GFX_resize PLAT_resizeVideo // (int w, int h, int pitch); +#define GFX_setSharpness PLAT_setSharpness // (int sharpness) +#define GFX_setEffectColor PLAT_setEffectColor // (int color) +#define GFX_setEffect PLAT_setEffect // (int effect) +#define GFX_setOverlay PLAT_setOverlay // (int effect) +#define GFX_setOffsetX PLAT_setOffsetX // (int effect) +#define GFX_setOffsetY PLAT_setOffsetY // (int effect) +#define GFX_drawOnLayer PLAT_drawOnLayer //(SDL_Surface *inputSurface,int x, int y) +#define GFX_clearLayers PLAT_clearLayers //(SDL_Surface *inputSurface,int x, int y) #define GFX_captureRendererToSurface PLAT_captureRendererToSurface //(void) -#define GFX_animateSurface PLAT_animateSurface //(SDL_Surface *inputSurface,int x, int y) -#define GFX_animateSurfaceOpacity PLAT_animateSurfaceOpacity //(SDL_Surface *inputSurface,int x, int y) -#define GFX_animateAndFadeSurface PLAT_animateAndFadeSurface //(SDL_Surface *inputSurface,int x, int y) +#define GFX_animateSurface PLAT_animateSurface //(SDL_Surface *inputSurface,int x, int y) +#define GFX_animateSurfaceOpacity PLAT_animateSurfaceOpacity //(SDL_Surface *inputSurface,int x, int y) +#define GFX_animateAndFadeSurface PLAT_animateAndFadeSurface //(SDL_Surface *inputSurface,int x, int y) #define GFX_resetScrollText PLAT_resetScrollText #define GFX_scrollTextTexture PLAT_scrollTextTexture -#define GFX_flipHidden PLAT_flipHidden //(void) +#define GFX_flipHidden PLAT_flipHidden //(void) #define GFX_GL_screenCapture PLAT_GL_screenCapture //(void) void GFX_setMode(int mode); int GFX_hdmiChanged(void); SDL_Color /*GFX_*/ uintToColour(uint32_t colour); -#define GFX_clear PLAT_clearVideo // (SDL_Surface* screen) +#define GFX_clear PLAT_clearVideo // (SDL_Surface* screen) #define GFX_clearAll PLAT_clearAll // (void) void GFX_startFrame(void); -void GFX_flip(SDL_Surface* screen); +void GFX_flip(SDL_Surface *screen); void PLAT_flipHidden(); -void GFX_flip_fixed_rate(SDL_Surface* screen, double target_fps); // if target_fps is 0, then use the native screen FPS -#define GFX_supportsOverscan PLAT_supportsOverscan // (void) -void GFX_sync(void); // call this to maintain 60fps when not calling GFX_flip() this frame -void GFX_delay(void); // gfx_sync() is only for everywhere where there is no audio buffer to rely on for delaying, stupid so doing gfx_delay() for like waiting for input loop in binding menu. Need to remove gfx_sync() everwhere eventually +void GFX_flip_fixed_rate(SDL_Surface *screen, double target_fps); // if target_fps is 0, then use the native screen FPS +#define GFX_supportsOverscan PLAT_supportsOverscan // (void) +void GFX_sync(void); // call this to maintain 60fps when not calling GFX_flip() this frame +void GFX_delay(void); // gfx_sync() is only for everywhere where there is no audio buffer to rely on for delaying, + // stupid so doing gfx_delay() for like waiting for input loop in binding menu. Need to remove + // gfx_sync() everwhere eventually void GFX_quit(void); enum { @@ -292,22 +293,26 @@ enum { int GFX_getVsync(void); void GFX_setVsync(int vsync); -int GFX_truncateText(TTF_Font* font, const char* in_name, char* out_name, int max_width, int padding); // returns final width -int PLAT_resetScrollText(TTF_Font* font, const char* in_name,int max_width); -void GFX_scrollTextSurface(TTF_Font* font, const char* in_name, SDL_Surface** out_surface, int max_width, int height, int padding, SDL_Color color,float heightratio); // returns final width -int GFX_getTextWidth(TTF_Font* font, const char* in_name, char* out_name, int max_width, int padding); // returns final width -int GFX_getTextHeight(TTF_Font* font, const char* in_name, char* out_name, int max_width, int padding); // returns final width -int GFX_wrapText(TTF_Font* font, char* str, int max_width, int max_lines); - -#define GFX_getScaler PLAT_getScaler // scaler_t:(GFX_Renderer* renderer) -#define GFX_blitRenderer PLAT_blitRenderer // void:(GFX_Renderer* renderer) -#define GFX_setShaders PLAT_setShaders // void:(GFX_Renderer* renderer) -#define GFX_resetShaders PLAT_resetShaders // void:(GFX_Renderer* renderer) -#define GFX_clearShaders PLAT_clearShaders // void:(GFX_Renderer* renderer) -#define GFX_updateShader PLAT_updateShader // void:(GFX_Renderer* renderer) -#define GFX_initShaders PLAT_initShaders // void:(GFX_Renderer* renderer) - -scaler_t GFX_getAAScaler(GFX_Renderer* renderer); +int GFX_truncateText(TTF_Font *font, const char *in_name, char *out_name, int max_width, + int padding); // returns final width +int PLAT_resetScrollText(TTF_Font *font, const char *in_name, int max_width); +void GFX_scrollTextSurface(TTF_Font *font, const char *in_name, SDL_Surface **out_surface, int max_width, int height, + int padding, SDL_Color color, float heightratio); // returns final width +int GFX_getTextWidth(TTF_Font *font, const char *in_name, char *out_name, int max_width, + int padding); // returns final width +int GFX_getTextHeight(TTF_Font *font, const char *in_name, char *out_name, int max_width, + int padding); // returns final width +int GFX_wrapText(TTF_Font *font, char *str, int max_width, int max_lines); + +#define GFX_getScaler PLAT_getScaler // scaler_t:(GFX_Renderer* renderer) +#define GFX_blitRenderer PLAT_blitRenderer // void:(GFX_Renderer* renderer) +#define GFX_setShaders PLAT_setShaders // void:(GFX_Renderer* renderer) +#define GFX_resetShaders PLAT_resetShaders // void:(GFX_Renderer* renderer) +#define GFX_clearShaders PLAT_clearShaders // void:(GFX_Renderer* renderer) +#define GFX_updateShader PLAT_updateShader // void:(GFX_Renderer* renderer) +#define GFX_initShaders PLAT_initShaders // void:(GFX_Renderer* renderer) + +scaler_t GFX_getAAScaler(GFX_Renderer *renderer); void GFX_freeAAScaler(void); // calls the appropriate scale function based on the enum value. @@ -321,35 +326,36 @@ SDL_Rect GFX_blitScaleAspect(SDL_Surface *src, SDL_Surface *dst); SDL_Rect GFX_blitScaleToFill(SDL_Surface *src, SDL_Surface *dst); // NOTE: all dimensions should be pre-scaled -void GFX_blitSurfaceColor(SDL_Surface* src, SDL_Rect* src_rect, SDL_Surface* dst, SDL_Rect* dst_rect, uint32_t asset_color); -void GFX_blitAssetColor(int asset, SDL_Rect* src_rect, SDL_Surface* dst, SDL_Rect* dst_rect, uint32_t asset_color); -void GFX_blitAsset(int asset, SDL_Rect* src_rect, SDL_Surface* dst, SDL_Rect* dst_rect); -void GFX_blitPillColor(int asset, SDL_Surface* dst, SDL_Rect* dst_rect, uint32_t asset_color, uint32_t fill_color); -void GFX_blitPill(int asset, SDL_Surface* dst, SDL_Rect* dst_rect); -void GFX_blitPillLight(int asset, SDL_Surface* dst, SDL_Rect* dst_rect); -void GFX_blitPillDark(int asset, SDL_Surface* dst, SDL_Rect* dst_rect); -void GFX_blitRect(int asset, SDL_Surface* dst, SDL_Rect* dst_rect); -void GFX_blitRectColor(int asset, SDL_Surface* dst, SDL_Rect* dst_rect, uint32_t asset_color); -void GFX_blitBattery(SDL_Surface* dst, SDL_Rect* dst_rect); +void GFX_blitSurfaceColor(SDL_Surface *src, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect, + uint32_t asset_color); +void GFX_blitAssetColor(int asset, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color); +void GFX_blitAsset(int asset, SDL_Rect *src_rect, SDL_Surface *dst, SDL_Rect *dst_rect); +void GFX_blitPillColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color, uint32_t fill_color); +void GFX_blitPill(int asset, SDL_Surface *dst, SDL_Rect *dst_rect); +void GFX_blitPillLight(int asset, SDL_Surface *dst, SDL_Rect *dst_rect); +void GFX_blitPillDark(int asset, SDL_Surface *dst, SDL_Rect *dst_rect); +void GFX_blitRect(int asset, SDL_Surface *dst, SDL_Rect *dst_rect); +void GFX_blitRectColor(int asset, SDL_Surface *dst, SDL_Rect *dst_rect, uint32_t asset_color); +void GFX_blitBattery(SDL_Surface *dst, SDL_Rect *dst_rect); void GFX_blitBatteryAtPosition(SDL_Surface *dst, int x, int y); -int GFX_getButtonWidth(char* hint, char* button); -void GFX_blitButton(char* hint, char*button, SDL_Surface* dst, SDL_Rect* dst_rect); -void GFX_blitMessage(TTF_Font* font, char* msg, SDL_Surface* dst, SDL_Rect* dst_rect); - -int GFX_blitHardwareGroup(SDL_Surface* dst, int show_setting); -void GFX_blitHardwareHints(SDL_Surface* dst, int show_setting); -int GFX_blitButtonGroup(char** hints, int primary, SDL_Surface* dst, int align_right); - -void GFX_assetRect(int asset, SDL_Rect* dst_rect); -void GFX_sizeText(TTF_Font* font, const char* str, int leading, int* w, int* h); -void GFX_blitText(TTF_Font* font, const char* str, int leading, SDL_Color color, SDL_Surface* dst, SDL_Rect* dst_rect); -void GFX_setAmbientColor(const void *data, unsigned width, unsigned height, size_t pitch,int mode); - -void GFX_ApplyRoundedCorners(SDL_Surface* surface, SDL_Rect* rect, int radius); -void GFX_ApplyRoundedCorners16(SDL_Surface* surface, SDL_Rect* rect, int radius); -void GFX_ApplyRoundedCorners_RGBA4444(SDL_Surface* surface, SDL_Rect* rect, int radius); -void GFX_ApplyRoundedCorners_RGBA8888(SDL_Surface* surface, SDL_Rect* rect, int radius); -void BlitRGBA4444toRGB565(SDL_Surface* src, SDL_Surface* dest, SDL_Rect* dest_rect); +int GFX_getButtonWidth(char *hint, char *button); +void GFX_blitButton(char *hint, char *button, SDL_Surface *dst, SDL_Rect *dst_rect); +void GFX_blitMessage(TTF_Font *font, char *msg, SDL_Surface *dst, SDL_Rect *dst_rect); + +int GFX_blitHardwareGroup(SDL_Surface *dst, int show_setting); +void GFX_blitHardwareHints(SDL_Surface *dst, int show_setting); +int GFX_blitButtonGroup(char **hints, int primary, SDL_Surface *dst, int align_right); + +void GFX_assetRect(int asset, SDL_Rect *dst_rect); +void GFX_sizeText(TTF_Font *font, const char *str, int leading, int *w, int *h); +void GFX_blitText(TTF_Font *font, const char *str, int leading, SDL_Color color, SDL_Surface *dst, SDL_Rect *dst_rect); +void GFX_setAmbientColor(const void *data, unsigned width, unsigned height, size_t pitch, int mode); + +void GFX_ApplyRoundedCorners(SDL_Surface *surface, SDL_Rect *rect, int radius); +void GFX_ApplyRoundedCorners16(SDL_Surface *surface, SDL_Rect *rect, int radius); +void GFX_ApplyRoundedCorners_RGBA4444(SDL_Surface *surface, SDL_Rect *rect, int radius); +void GFX_ApplyRoundedCorners_RGBA8888(SDL_Surface *surface, SDL_Rect *rect, int radius); +void BlitRGBA4444toRGB565(SDL_Surface *src, SDL_Surface *dest, SDL_Rect *dest_rect); /////////////////////////////// typedef struct SND_Frame { @@ -358,13 +364,13 @@ typedef struct SND_Frame { } SND_Frame; typedef struct { - SND_Frame* frames; + SND_Frame *frames; int frame_count; } ResampledFrames; void SND_init(double sample_rate, double frame_rate); -size_t SND_batchSamples(const SND_Frame* frames, size_t frame_count); -size_t SND_batchSamples_fixed_rate(const SND_Frame* frames, size_t frame_count); +size_t SND_batchSamples(const SND_Frame *frames, size_t frame_count); +size_t SND_batchSamples_fixed_rate(const SND_Frame *frames, size_t frame_count); void SND_quit(void); void SND_resetAudio(double sample_rate, double frame_rate); void SND_pauseAudio(bool paused); @@ -393,13 +399,13 @@ typedef struct LID_Context { extern LID_Context lid; void PLAT_initLid(void); -int PLAT_lidChanged(int* state); +int PLAT_lidChanged(int *state); void PLAT_getCPUTemp(); /////////////////////////////// typedef struct PAD_Axis { - int x; - int y; + int x; + int y; } PAD_Axis; typedef struct PAD_Context { int is_pressed; @@ -412,7 +418,7 @@ typedef struct PAD_Context { } PAD_Context; extern PAD_Context pad; -#define PAD_REPEAT_DELAY 300 +#define PAD_REPEAT_DELAY 300 #define PAD_REPEAT_INTERVAL 100 #define PAD_init PLAT_initInput @@ -433,8 +439,10 @@ int PAD_isPressed(int btn); int PAD_justReleased(int btn); int PAD_justRepeated(int btn); -int PAD_tappedMenu(uint32_t now); // special case, returns 1 on release of BTN_MENU within 250ms if BTN_PLUS/BTN_MINUS haven't been pressed -int PAD_tappedSelect(uint32_t now); // special case, returns 1 on release of BTN_SELECT within 250ms if BTN_PLUS/BTN_MINUS haven't been pressed +int PAD_tappedMenu(uint32_t now); // special case, returns 1 on release of BTN_MENU within 250ms if BTN_PLUS/BTN_MINUS + // haven't been pressed +int PAD_tappedSelect(uint32_t now); // special case, returns 1 on release of BTN_SELECT within 250ms if + // BTN_PLUS/BTN_MINUS haven't been pressed /////////////////////////////// #define VIB_sleepStrength 4 @@ -461,7 +469,7 @@ void PWR_quit(void); void PWR_warn(int enable); int PWR_ignoreSettingInput(int btn, int show_setting); -void PWR_update(int* dirty, int* show_setting, PWR_callback_t before_sleep, PWR_callback_t after_sleep); +void PWR_update(int *dirty, int *show_setting, PWR_callback_t before_sleep, PWR_callback_t after_sleep); void PWR_updateFrequency(int secs, int updateWifi); void PWR_disablePowerOff(void); @@ -483,13 +491,13 @@ int PWR_getBattery(void); // rules-based presets managed and applied by LEDS_applyRules() enum LightProfile { - LIGHT_PROFILE_DEFAULT = 0, // configured via LedControl - LIGHT_PROFILE_OFF = 1, // all forced off - LIGHT_PROFILE_LOW_BATTERY = 2, // low battery warning + LIGHT_PROFILE_DEFAULT = 0, // configured via LedControl + LIGHT_PROFILE_OFF = 1, // all forced off + LIGHT_PROFILE_LOW_BATTERY = 2, // low battery warning LIGHT_PROFILE_CRITICAL_BATTERY = 3, // critical battery warning - LIGHT_PROFILE_CHARGING = 4, // derived from default - LIGHT_PROFILE_SLEEP = 5, // sleep mode - LIGHT_PROFILE_AMBIENT = 6, // ambient mode + LIGHT_PROFILE_CHARGING = 4, // derived from default + LIGHT_PROFILE_SLEEP = 5, // sleep mode + LIGHT_PROFILE_AMBIENT = 6, // ambient mode LIGHT_PROFILE_COUNT }; @@ -501,7 +509,7 @@ void LEDS_initLeds(); void LEDS_applyRules(); // temporary overrides outside of the scope of LEDS_applyRules -// these will survive LEDS_applyRules() and need to be manually revoked, e.g. +// these will survive LEDS_applyRules() and need to be manually revoked, e.g. /* LEDS_applyRules(); // applies rules LEDS_pushProfile(LIGHT_PROFILE_AMBIENT); // manual override @@ -537,7 +545,7 @@ enum { FILE *PLAT_OpenSettings(const char *filename); FILE *PLAT_WriteSettings(const char *filename); -char* PLAT_findFileInDir(const char *directory, const char *filename); +char *PLAT_findFileInDir(const char *directory, const char *filename); void PLAT_initInput(void); void PLAT_updateInput(const SDL_Event *event); void PLAT_quitInput(void); @@ -545,60 +553,44 @@ void PLAT_quitInput(void); void PLAT_pollInput(void); int PLAT_shouldWake(void); -SDL_Surface* PLAT_initVideo(void); +SDL_Surface *PLAT_initVideo(void); void PLAT_quitVideo(void); uint32_t PLAT_get_dominant_color(void); -void PLAT_clearVideo(SDL_Surface* screen); +void PLAT_clearVideo(SDL_Surface *screen); void PLAT_clearAll(void); void PLAT_setVsync(int vsync); -SDL_Surface* PLAT_resizeVideo(int w, int h, int pitch); +SDL_Surface *PLAT_resizeVideo(int w, int h, int pitch); void PLAT_setSharpness(int sharpness); void PLAT_setEffectColor(int color); void PLAT_setEffect(int effect); -void PLAT_setOverlay(const char* filename, const char* tag); +void PLAT_setOverlay(const char *filename, const char *tag); void PLAT_setOffsetX(int x); void PLAT_setOffsetY(int y); -void PLAT_drawOnLayer(SDL_Surface *inputSurface, int x, int y, int w, int h, float brightness, bool maintainAspectRatio,int layer); +void PLAT_drawOnLayer(SDL_Surface *inputSurface, int x, int y, int w, int h, float brightness, bool maintainAspectRatio, + int layer); void PLAT_clearLayers(int layer); -SDL_Surface* PLAT_captureRendererToSurface(); -void PLAT_animateSurface( - SDL_Surface *inputSurface, - int x, int y, - int target_x, int target_y, - int w, int h, - int duration_ms, - int start_opacity, - int target_opacity, - int layer -); -void PLAT_animateAndFadeSurface( - SDL_Surface *inputSurface, - int x, int y, int target_x, int target_y, int w, int h, int duration_ms, - SDL_Surface *fadeSurface, - int fade_x, int fade_y, int fade_w, int fade_h, - int start_opacity, int target_opacity, int layer -); - -void PLAT_animateSurfaceOpacity(SDL_Surface *inputSurface, int x, int y, int w, int h, - int start_opacity, int target_opacity, int duration_ms, int layer); - -void PLAT_scrollTextTexture( - TTF_Font* font, - const char* in_name, - int x, int y, // Position on target layer - int w, int h, // Clipping width and height - SDL_Color color, - float transparency -); -void drawTextWithCache(TTF_Font* font, const char* text, SDL_Color color, SDL_Rect* destRect); +SDL_Surface *PLAT_captureRendererToSurface(); +void PLAT_animateSurface(SDL_Surface *inputSurface, int x, int y, int target_x, int target_y, int w, int h, + int duration_ms, int start_opacity, int target_opacity, int layer); +void PLAT_animateAndFadeSurface(SDL_Surface *inputSurface, int x, int y, int target_x, int target_y, int w, int h, + int duration_ms, SDL_Surface *fadeSurface, int fade_x, int fade_y, int fade_w, + int fade_h, int start_opacity, int target_opacity, int layer); + +void PLAT_animateSurfaceOpacity(SDL_Surface *inputSurface, int x, int y, int w, int h, int start_opacity, + int target_opacity, int duration_ms, int layer); + +void PLAT_scrollTextTexture(TTF_Font *font, const char *in_name, int x, int y, // Position on target layer + int w, int h, // Clipping width and height + SDL_Color color, float transparency); +void drawTextWithCache(TTF_Font *font, const char *text, SDL_Color color, SDL_Rect *destRect); void PLAT_vsync(int remaining); -scaler_t PLAT_getScaler(GFX_Renderer* renderer); -void PLAT_blitRenderer(GFX_Renderer* renderer); -void PLAT_flip(SDL_Surface* screen, int sync); +scaler_t PLAT_getScaler(GFX_Renderer *renderer); +void PLAT_blitRenderer(GFX_Renderer *renderer); +void PLAT_flip(SDL_Surface *screen, int sync); void PLAT_GL_Swap(); void GFX_GL_Swap(); -unsigned char* PLAT_GL_screenCapture(int* outWidth, int* outHeight); -unsigned char* PLAT_pixelscaler(const unsigned char* src, int sw, int sh, int scale, int* outW, int* outH); +unsigned char *PLAT_GL_screenCapture(int *outWidth, int *outHeight); +unsigned char *PLAT_pixelscaler(const unsigned char *src, int sw, int sh, int scale, int *outW, int *outH); void PLAT_GPU_Flip(); void PLAT_setShaders(int nr); void PLAT_resetShaders(); @@ -609,21 +601,21 @@ void PLAT_setShader3Filter(int value); void PLAT_setShaderUpscale1(int nr); void PLAT_setShaderUpscale2(int nr); void PLAT_setShaderUpscale3(int nr); -void PLAT_setShader1(const char* filename); -void PLAT_setShader2(const char* filename); -void PLAT_setShader3(const char* filename); +void PLAT_setShader1(const char *filename); +void PLAT_setShader2(const char *filename); +void PLAT_setShader3(const char *filename); void PLAT_updateShader(int i, const char *filename, int *scale, int *filter, int *scaletype, int *inputtype); void PLAT_initShaders(); -ShaderParam* PLAT_getShaderPragmas(int i); +ShaderParam *PLAT_getShaderPragmas(int i); int PLAT_supportsOverscan(void); -SDL_Surface* PLAT_initOverlay(void); +SDL_Surface *PLAT_initOverlay(void); void PLAT_quitOverlay(void); void PLAT_enableOverlay(int enable); - + #define PWR_LOW_CHARGE 10 -void PLAT_getBatteryStatus(int* is_charging, int* charge); // 0,1 and 0,10,20,40,60,80,100 -void PLAT_getBatteryStatusFine(int* is_charging, int* charge); // 0,1 and 0-100 +void PLAT_getBatteryStatus(int *is_charging, int *charge); // 0,1 and 0,10,20,40,60,80,100 +void PLAT_getBatteryStatusFine(int *is_charging, int *charge); // 0,1 and 0-100 void PLAT_enableBacklight(int enable); int PLAT_supportsDeepSleep(void); int PLAT_deepSleep(void); @@ -635,7 +627,7 @@ void PLAT_setCustomCPUSpeed(int speed); void PLAT_setRumble(int strength); int PLAT_pickSampleRate(int requested, int max); -char* PLAT_getModel(void); +char *PLAT_getModel(void); void PLAT_getOsVersionInfo(char *output_str, size_t max_len); void PLAT_updateNetworkStatus(); bool PLAT_btIsConnected(void); @@ -670,7 +662,7 @@ void PLAT_clearTurbo(); void PLAT_initTimezones(); void PLAT_getTimezones(char timezones[MAX_TIMEZONES][MAX_TZ_LENGTH], int *tz_count); char *PLAT_getCurrentTimezone(); -void PLAT_setCurrentTimezone(const char*); +void PLAT_setCurrentTimezone(const char *); bool PLAT_getNetworkTimeSync(void); void PLAT_setNetworkTimeSync(bool on); @@ -685,7 +677,7 @@ void PLAT_setNetworkTimeSync(bool on); #define SSID_MAX 64 #define SCAN_MAX_RESULTS 128 -//#define LIST_NETWORK_MAX 4096 +// #define LIST_NETWORK_MAX 4096 typedef enum { SECURITY_NONE = 0, @@ -736,9 +728,9 @@ void PLAT_wifiForget(char *ssid, WifiSecurityType sec); // attempt to connect to this SSID, using, stored credentials. // \sa PLAT_wifiHasCredentials void PLAT_wifiConnect(char *ssid, WifiSecurityType sec); -// attempt to connect to this SSID with password given. +// attempt to connect to this SSID with password given. // If successful, stores credentials with wpa_supplicant. -void PLAT_wifiConnectPass(const char *ssid, WifiSecurityType sec, const char* pass); +void PLAT_wifiConnectPass(const char *ssid, WifiSecurityType sec, const char *pass); // disconnect from any active network void PLAT_wifiDisconnect(); // enable wifi diagnostic logging @@ -769,24 +761,24 @@ typedef enum { } BluetoothDeviceType; struct BT_device { - char addr[18]; // MAX_BT_ADDR_LEN + char addr[18]; // MAX_BT_ADDR_LEN char name[249]; // MAX_BT_NAME_LEN BluetoothDeviceType kind; }; -//struct BT_deviceUUID { +// struct BT_deviceUUID { // char *uuid; // char *uuid_name; -//}; +// }; struct BT_devicePaired { - char remote_addr[18]; // MAX_BT_ADDR_LEN + char remote_addr[18]; // MAX_BT_ADDR_LEN char remote_name[249]; // MAX_BT_NAME_LEN int16_t rssi; bool is_bonded; bool is_connected; - //int uuid_len; - //BT_deviceUUID *uuids; + // int uuid_len; + // BT_deviceUUID *uuids; }; // initializes our BT context and synchronizes it with the current system state diff --git a/workspace/all/common/config.c b/workspace/all/common/config.c index 1dd5a9e15..47bf40fa6 100644 --- a/workspace/all/common/config.c +++ b/workspace/all/common/config.c @@ -13,911 +13,802 @@ uint32_t THEME_COLOR5_255; uint32_t THEME_COLOR6_255; uint32_t THEME_COLOR7_255; -static inline uint32_t HexToUint32_unmapped(const char *hexColor) { - // Convert the hex string to an unsigned long - uint32_t value = (uint32_t)strtoul(hexColor, NULL, 16); - return value; +static inline uint32_t HexToUint32_unmapped(const char *hexColor) +{ + // Convert the hex string to an unsigned long + uint32_t value = (uint32_t)strtoul(hexColor, NULL, 16); + return value; } void CFG_defaults(NextUISettings *cfg) { - if (!cfg) - return; - - NextUISettings defaults = { - .font = CFG_DEFAULT_FONT_ID, - .color1_255 = CFG_DEFAULT_COLOR1, - .color2_255 = CFG_DEFAULT_COLOR2, - .color3_255 = CFG_DEFAULT_COLOR3, - .color4_255 = CFG_DEFAULT_COLOR4, - .color5_255 = CFG_DEFAULT_COLOR5, - .color6_255 = CFG_DEFAULT_COLOR6, - .color7_255 = CFG_DEFAULT_COLOR7, - .thumbRadius = CFG_DEFAULT_THUMBRADIUS, - .gameArtWidth = CFG_DEFAULT_GAMEARTWIDTH, + if (!cfg) + return; + + NextUISettings defaults = { + .font = CFG_DEFAULT_FONT_ID, + .color1_255 = CFG_DEFAULT_COLOR1, + .color2_255 = CFG_DEFAULT_COLOR2, + .color3_255 = CFG_DEFAULT_COLOR3, + .color4_255 = CFG_DEFAULT_COLOR4, + .color5_255 = CFG_DEFAULT_COLOR5, + .color6_255 = CFG_DEFAULT_COLOR6, + .color7_255 = CFG_DEFAULT_COLOR7, + .thumbRadius = CFG_DEFAULT_THUMBRADIUS, + .gameArtWidth = CFG_DEFAULT_GAMEARTWIDTH, .showFolderNamesAtRoot = CFG_DEFAULT_SHOWFOLDERNAMESATROOT, - .showClock = CFG_DEFAULT_SHOWCLOCK, - .clock24h = CFG_DEFAULT_CLOCK24H, - .showBatteryPercent = CFG_DEFAULT_SHOWBATTERYPERCENT, - .showMenuAnimations = CFG_DEFAULT_SHOWMENUANIMATIONS, - .showMenuTransitions = CFG_DEFAULT_SHOWMENUTRANSITIONS, - .showRecents = CFG_DEFAULT_SHOWRECENTS, - .showTools = CFG_DEFAULT_SHOWTOOLS, - .showGameArt = CFG_DEFAULT_SHOWGAMEART, - .gameSwitcherScaling = CFG_DEFAULT_GAMESWITCHERSCALING, - .defaultView = CFG_DEFAULT_VIEW, - .showQuickSwitcherUi = CFG_DEFAULT_SHOWQUICKWITCHERUI, + .showClock = CFG_DEFAULT_SHOWCLOCK, + .clock24h = CFG_DEFAULT_CLOCK24H, + .showBatteryPercent = CFG_DEFAULT_SHOWBATTERYPERCENT, + .showMenuAnimations = CFG_DEFAULT_SHOWMENUANIMATIONS, + .showMenuTransitions = CFG_DEFAULT_SHOWMENUTRANSITIONS, + .showRecents = CFG_DEFAULT_SHOWRECENTS, + .showTools = CFG_DEFAULT_SHOWTOOLS, + .showGameArt = CFG_DEFAULT_SHOWGAMEART, + .gameSwitcherScaling = CFG_DEFAULT_GAMESWITCHERSCALING, + .defaultView = CFG_DEFAULT_VIEW, + .showQuickSwitcherUi = CFG_DEFAULT_SHOWQUICKWITCHERUI, - .muteLeds = CFG_DEFAULT_MUTELEDS, + .muteLeds = CFG_DEFAULT_MUTELEDS, - .screenTimeoutSecs = CFG_DEFAULT_SCREENTIMEOUTSECS, - .suspendTimeoutSecs = CFG_DEFAULT_SUSPENDTIMEOUTSECS, + .screenTimeoutSecs = CFG_DEFAULT_SCREENTIMEOUTSECS, + .suspendTimeoutSecs = CFG_DEFAULT_SUSPENDTIMEOUTSECS, - .haptics = CFG_DEFAULT_HAPTICS, - .romsUseFolderBackground = CFG_DEFAULT_ROMSUSEFOLDERBACKGROUND, - .saveFormat = CFG_DEFAULT_SAVEFORMAT, - .stateFormat = CFG_DEFAULT_STATEFORMAT, - .useExtractedFileName = CFG_DEFAULT_EXTRACTEDFILENAME, + .haptics = CFG_DEFAULT_HAPTICS, + .romsUseFolderBackground = CFG_DEFAULT_ROMSUSEFOLDERBACKGROUND, + .saveFormat = CFG_DEFAULT_SAVEFORMAT, + .stateFormat = CFG_DEFAULT_STATEFORMAT, + .useExtractedFileName = CFG_DEFAULT_EXTRACTEDFILENAME, - .wifi = CFG_DEFAULT_WIFI, - .wifiDiagnostics = CFG_DEFAULT_WIFI_DIAG, - .bluetooth = CFG_DEFAULT_BLUETOOTH, - .bluetoothDiagnostics = CFG_DEFAULT_BLUETOOTH_DIAG, - .bluetoothSamplerateLimit = CFG_DEFAULT_BLUETOOTH_MAXRATE, -}; + .wifi = CFG_DEFAULT_WIFI, + .wifiDiagnostics = CFG_DEFAULT_WIFI_DIAG, + .bluetooth = CFG_DEFAULT_BLUETOOTH, + .bluetoothDiagnostics = CFG_DEFAULT_BLUETOOTH_DIAG, + .bluetoothSamplerateLimit = CFG_DEFAULT_BLUETOOTH_MAXRATE, + }; - *cfg = defaults; + *cfg = defaults; } void CFG_init(FontLoad_callback_t cb, ColorSet_callback_t ccb) { - CFG_defaults(&settings); - settings.onFontChange = cb; - settings.onColorSet = ccb; - bool fontLoaded = false; - - char settingsPath[MAX_PATH]; - sprintf(settingsPath, "%s/minuisettings.txt", SHARED_USERDATA_PATH); - FILE *file = fopen(settingsPath, "r"); - if (file == NULL) - { - printf("[CFG] Unable to open settings file, loading defaults\n"); - } - else - { - char line[256]; - while (fgets(line, sizeof(line), file)) - { - int temp_value; - uint32_t temp_color; - if (sscanf(line, "font=%i", &temp_value) == 1) - { - CFG_setFontId(temp_value); - fontLoaded = true; - continue; - } - if (sscanf(line, "color1=%x", &temp_color) == 1) - { - char hexColor[7]; - snprintf(hexColor, sizeof(hexColor), "%06x", temp_color); - CFG_setColor(1, HexToUint32_unmapped(hexColor)); - continue; - } - if (sscanf(line, "color2=%x", &temp_color) == 1) - { - CFG_setColor(2, temp_color); - continue; - } - if (sscanf(line, "color3=%x", &temp_color) == 1) - { - CFG_setColor(3, temp_color); - continue; - } - if (sscanf(line, "color4=%x", &temp_color) == 1) - { - CFG_setColor(4, temp_color); - continue; - } - if (sscanf(line, "color5=%x", &temp_color) == 1) - { - CFG_setColor(5, temp_color); - continue; - } - if (sscanf(line, "color6=%x", &temp_color) == 1) - { - CFG_setColor(6, temp_color); - continue; - } - if (sscanf(line, "color7=%x", &temp_color) == 1) - { - CFG_setColor(7, temp_color); - continue; - } - if (sscanf(line, "radius=%i", &temp_value) == 1) - { - CFG_setThumbnailRadius(temp_value); - continue; - } - if (sscanf(line, "showclock=%i", &temp_value) == 1) - { - CFG_setShowClock((bool)temp_value); - continue; - } - if (sscanf(line, "clock24h=%i", &temp_value) == 1) - { - CFG_setClock24H((bool)temp_value); - continue; - } - if (sscanf(line, "batteryperc=%i", &temp_value) == 1) - { - CFG_setShowBatteryPercent((bool)temp_value); - continue; - } - if (sscanf(line, "menuanim=%i", &temp_value) == 1) - { - CFG_setMenuAnimations((bool)temp_value); - continue; - } - if (sscanf(line, "menutransitions=%i", &temp_value) == 1) - { - CFG_setMenuTransitions((bool)temp_value); - continue; - } - if (sscanf(line, "recents=%i", &temp_value) == 1) - { - CFG_setShowRecents((bool)temp_value); - continue; - } - if (sscanf(line, "tools=%i", &temp_value) == 1) - { - CFG_setShowTools((bool)temp_value); - continue; - } - if (sscanf(line, "gameart=%i", &temp_value) == 1) - { - CFG_setShowGameArt((bool)temp_value); - continue; - } - if (sscanf(line, "screentimeout=%i", &temp_value) == 1) - { - CFG_setScreenTimeoutSecs(temp_value); - continue; - } - if (sscanf(line, "showfoldernamesatroot=%i", &temp_value) == 1) - { - CFG_setShowFolderNamesAtRoot((bool)temp_value); - continue; - } - if (sscanf(line, "suspendTimeout=%i", &temp_value) == 1) - { - CFG_setSuspendTimeoutSecs(temp_value); - continue; - } - if (sscanf(line, "switcherscale=%i", &temp_value) == 1) - { - CFG_setGameSwitcherScaling(temp_value); - continue; - } - if (sscanf(line, "haptics=%i", &temp_value) == 1) - { - CFG_setHaptics((bool)temp_value); - continue; - } - if (sscanf(line, "romfolderbg=%i", &temp_value) == 1) - { - CFG_setRomsUseFolderBackground((bool)temp_value); - continue; - } - if (sscanf(line, "saveFormat=%i", &temp_value) == 1) - { - CFG_setSaveFormat(temp_value); - continue; - } - if (sscanf(line, "stateFormat=%i", &temp_value) == 1) - { - CFG_setStateFormat(temp_value); - continue; - } - if (sscanf(line, "useExtractedFileName=%i", &temp_value) == 1) - { - CFG_setUseExtractedFileName((bool)temp_value); - continue; - } - if (sscanf(line, "muteLeds=%i", &temp_value) == 1) - { - CFG_setMuteLEDs(temp_value); - continue; - } - if (sscanf(line, "artWidth=%i", &temp_value) == 1) - { - CFG_setGameArtWidth((double)temp_value / 100.0); - continue; - } - if (sscanf(line, "wifi=%i", &temp_value) == 1) - { - CFG_setWifi((bool)temp_value); - continue; - } - if (sscanf(line, "defaultView=%i", &temp_value) == 1) - { - CFG_setDefaultView(temp_value); - continue; - } - if (sscanf(line, "quickSwitcherUi=%i", &temp_value) == 1) - { - CFG_setShowQuickswitcherUI(temp_value); - continue; - } - if (sscanf(line, "wifiDiagnostics=%i", &temp_value) == 1) - { - CFG_setWifiDiagnostics(temp_value); - continue; - } - if (sscanf(line, "bluetooth=%i", &temp_value) == 1) - { - CFG_setBluetooth(temp_value); - continue; - } - if (sscanf(line, "btDiagnostics=%i", &temp_value) == 1) - { - CFG_setBluetoothDiagnostics(temp_value); - continue; - } - if (sscanf(line, "btMaxRate=%i", &temp_value) == 1) - { - CFG_setBluetoothSamplingrateLimit(temp_value); - continue; - } - } - fclose(file); - } - - // load gfx related stuff until we drop the indirection - CFG_setColor(1, CFG_getColor(1)); - CFG_setColor(2, CFG_getColor(2)); - CFG_setColor(3, CFG_getColor(3)); - CFG_setColor(4, CFG_getColor(4)); - CFG_setColor(5, CFG_getColor(5)); - CFG_setColor(6, CFG_getColor(6)); - CFG_setColor(7, CFG_getColor(7)); - // avoid reloading the font if not neccessary - if (!fontLoaded) - CFG_setFontId(CFG_getFontId()); + CFG_defaults(&settings); + settings.onFontChange = cb; + settings.onColorSet = ccb; + bool fontLoaded = false; + + char settingsPath[MAX_PATH]; + sprintf(settingsPath, "%s/minuisettings.txt", SHARED_USERDATA_PATH); + FILE *file = fopen(settingsPath, "r"); + if (file == NULL) { + printf("[CFG] Unable to open settings file, loading defaults\n"); + } else { + char line[256]; + while (fgets(line, sizeof(line), file)) { + int temp_value; + uint32_t temp_color; + if (sscanf(line, "font=%i", &temp_value) == 1) { + CFG_setFontId(temp_value); + fontLoaded = true; + continue; + } + if (sscanf(line, "color1=%x", &temp_color) == 1) { + char hexColor[7]; + snprintf(hexColor, sizeof(hexColor), "%06x", temp_color); + CFG_setColor(1, HexToUint32_unmapped(hexColor)); + continue; + } + if (sscanf(line, "color2=%x", &temp_color) == 1) { + CFG_setColor(2, temp_color); + continue; + } + if (sscanf(line, "color3=%x", &temp_color) == 1) { + CFG_setColor(3, temp_color); + continue; + } + if (sscanf(line, "color4=%x", &temp_color) == 1) { + CFG_setColor(4, temp_color); + continue; + } + if (sscanf(line, "color5=%x", &temp_color) == 1) { + CFG_setColor(5, temp_color); + continue; + } + if (sscanf(line, "color6=%x", &temp_color) == 1) { + CFG_setColor(6, temp_color); + continue; + } + if (sscanf(line, "color7=%x", &temp_color) == 1) { + CFG_setColor(7, temp_color); + continue; + } + if (sscanf(line, "radius=%i", &temp_value) == 1) { + CFG_setThumbnailRadius(temp_value); + continue; + } + if (sscanf(line, "showclock=%i", &temp_value) == 1) { + CFG_setShowClock((bool)temp_value); + continue; + } + if (sscanf(line, "clock24h=%i", &temp_value) == 1) { + CFG_setClock24H((bool)temp_value); + continue; + } + if (sscanf(line, "batteryperc=%i", &temp_value) == 1) { + CFG_setShowBatteryPercent((bool)temp_value); + continue; + } + if (sscanf(line, "menuanim=%i", &temp_value) == 1) { + CFG_setMenuAnimations((bool)temp_value); + continue; + } + if (sscanf(line, "menutransitions=%i", &temp_value) == 1) { + CFG_setMenuTransitions((bool)temp_value); + continue; + } + if (sscanf(line, "recents=%i", &temp_value) == 1) { + CFG_setShowRecents((bool)temp_value); + continue; + } + if (sscanf(line, "tools=%i", &temp_value) == 1) { + CFG_setShowTools((bool)temp_value); + continue; + } + if (sscanf(line, "gameart=%i", &temp_value) == 1) { + CFG_setShowGameArt((bool)temp_value); + continue; + } + if (sscanf(line, "screentimeout=%i", &temp_value) == 1) { + CFG_setScreenTimeoutSecs(temp_value); + continue; + } + if (sscanf(line, "showfoldernamesatroot=%i", &temp_value) == 1) { + CFG_setShowFolderNamesAtRoot((bool)temp_value); + continue; + } + if (sscanf(line, "suspendTimeout=%i", &temp_value) == 1) { + CFG_setSuspendTimeoutSecs(temp_value); + continue; + } + if (sscanf(line, "switcherscale=%i", &temp_value) == 1) { + CFG_setGameSwitcherScaling(temp_value); + continue; + } + if (sscanf(line, "haptics=%i", &temp_value) == 1) { + CFG_setHaptics((bool)temp_value); + continue; + } + if (sscanf(line, "romfolderbg=%i", &temp_value) == 1) { + CFG_setRomsUseFolderBackground((bool)temp_value); + continue; + } + if (sscanf(line, "saveFormat=%i", &temp_value) == 1) { + CFG_setSaveFormat(temp_value); + continue; + } + if (sscanf(line, "stateFormat=%i", &temp_value) == 1) { + CFG_setStateFormat(temp_value); + continue; + } + if (sscanf(line, "useExtractedFileName=%i", &temp_value) == 1) { + CFG_setUseExtractedFileName((bool)temp_value); + continue; + } + if (sscanf(line, "muteLeds=%i", &temp_value) == 1) { + CFG_setMuteLEDs(temp_value); + continue; + } + if (sscanf(line, "artWidth=%i", &temp_value) == 1) { + CFG_setGameArtWidth((double)temp_value / 100.0); + continue; + } + if (sscanf(line, "wifi=%i", &temp_value) == 1) { + CFG_setWifi((bool)temp_value); + continue; + } + if (sscanf(line, "defaultView=%i", &temp_value) == 1) { + CFG_setDefaultView(temp_value); + continue; + } + if (sscanf(line, "quickSwitcherUi=%i", &temp_value) == 1) { + CFG_setShowQuickswitcherUI(temp_value); + continue; + } + if (sscanf(line, "wifiDiagnostics=%i", &temp_value) == 1) { + CFG_setWifiDiagnostics(temp_value); + continue; + } + if (sscanf(line, "bluetooth=%i", &temp_value) == 1) { + CFG_setBluetooth(temp_value); + continue; + } + if (sscanf(line, "btDiagnostics=%i", &temp_value) == 1) { + CFG_setBluetoothDiagnostics(temp_value); + continue; + } + if (sscanf(line, "btMaxRate=%i", &temp_value) == 1) { + CFG_setBluetoothSamplingrateLimit(temp_value); + continue; + } + } + fclose(file); + } + + // load gfx related stuff until we drop the indirection + CFG_setColor(1, CFG_getColor(1)); + CFG_setColor(2, CFG_getColor(2)); + CFG_setColor(3, CFG_getColor(3)); + CFG_setColor(4, CFG_getColor(4)); + CFG_setColor(5, CFG_getColor(5)); + CFG_setColor(6, CFG_getColor(6)); + CFG_setColor(7, CFG_getColor(7)); + // avoid reloading the font if not neccessary + if (!fontLoaded) + CFG_setFontId(CFG_getFontId()); } int CFG_getFontId(void) { - return settings.font; + return settings.font; } void CFG_setFontId(int id) { - settings.font = clamp(id, 0, 2); + settings.font = clamp(id, 0, 2); - char *fontPath; - if (settings.font == 1) - fontPath = RES_PATH "/font1.ttf"; - else - fontPath = RES_PATH "/font2.ttf"; + char *fontPath; + if (settings.font == 1) + fontPath = RES_PATH "/font1.ttf"; + else + fontPath = RES_PATH "/font2.ttf"; - if(settings.onFontChange) - settings.onFontChange(fontPath); + if (settings.onFontChange) + settings.onFontChange(fontPath); } uint32_t CFG_getColor(int color_id) { - switch (color_id) - { - case 1: - return settings.color1_255; - case 2: - return settings.color2_255; - case 3: - return settings.color3_255; - case 4: - return settings.color4_255; - case 5: - return settings.color5_255; - case 6: - return settings.color6_255; - case 7: - return settings.color7_255; - default: - return 0; - } + switch (color_id) { + case 1: + return settings.color1_255; + case 2: + return settings.color2_255; + case 3: + return settings.color3_255; + case 4: + return settings.color4_255; + case 5: + return settings.color5_255; + case 6: + return settings.color6_255; + case 7: + return settings.color7_255; + default: + return 0; + } } void CFG_setColor(int color_id, uint32_t color) { - switch (color_id) - { - case 1: - settings.color1_255 = color; - THEME_COLOR1_255 = settings.color1_255; - break; - case 2: - settings.color2_255 = color; - THEME_COLOR2_255 = settings.color2_255; - break; - case 3: - settings.color3_255 = color; - THEME_COLOR3_255 = settings.color3_255; - break; - case 4: - settings.color4_255 = color; - THEME_COLOR4_255 = settings.color4_255; - break; - case 5: - settings.color5_255 = color; - THEME_COLOR5_255 = settings.color5_255; - break; - case 6: - settings.color6_255 = color; - THEME_COLOR6_255 = settings.color6_255; - break; - case 7: - settings.color7_255 = color; - THEME_COLOR7_255 = settings.color7_255; - break; - default: - break; - } - - if(settings.onColorSet) - settings.onColorSet(); + switch (color_id) { + case 1: + settings.color1_255 = color; + THEME_COLOR1_255 = settings.color1_255; + break; + case 2: + settings.color2_255 = color; + THEME_COLOR2_255 = settings.color2_255; + break; + case 3: + settings.color3_255 = color; + THEME_COLOR3_255 = settings.color3_255; + break; + case 4: + settings.color4_255 = color; + THEME_COLOR4_255 = settings.color4_255; + break; + case 5: + settings.color5_255 = color; + THEME_COLOR5_255 = settings.color5_255; + break; + case 6: + settings.color6_255 = color; + THEME_COLOR6_255 = settings.color6_255; + break; + case 7: + settings.color7_255 = color; + THEME_COLOR7_255 = settings.color7_255; + break; + default: + break; + } + + if (settings.onColorSet) + settings.onColorSet(); } bool CFG_getShowFolderNamesAtRoot(void) { - return settings.showFolderNamesAtRoot; + return settings.showFolderNamesAtRoot; } void CFG_setShowFolderNamesAtRoot(bool show) { - settings.showFolderNamesAtRoot = show; + settings.showFolderNamesAtRoot = show; CFG_sync(); } uint32_t CFG_getScreenTimeoutSecs(void) { - return settings.screenTimeoutSecs; + return settings.screenTimeoutSecs; } void CFG_setScreenTimeoutSecs(uint32_t secs) { - settings.screenTimeoutSecs = secs; - CFG_sync(); + settings.screenTimeoutSecs = secs; + CFG_sync(); } uint32_t CFG_getSuspendTimeoutSecs(void) { - return settings.suspendTimeoutSecs; + return settings.suspendTimeoutSecs; } void CFG_setSuspendTimeoutSecs(uint32_t secs) { - settings.suspendTimeoutSecs = secs; - CFG_sync(); + settings.suspendTimeoutSecs = secs; + CFG_sync(); } bool CFG_getShowClock(void) { - return settings.showClock; + return settings.showClock; } void CFG_setShowClock(bool show) { - settings.showClock = show; - CFG_sync(); + settings.showClock = show; + CFG_sync(); } bool CFG_getClock24H(void) { - return settings.clock24h; + return settings.clock24h; } void CFG_setClock24H(bool is24) { - settings.clock24h = is24; - CFG_sync(); + settings.clock24h = is24; + CFG_sync(); } bool CFG_getShowBatteryPercent(void) { - return settings.showBatteryPercent; + return settings.showBatteryPercent; } void CFG_setShowBatteryPercent(bool show) { - settings.showBatteryPercent = show; - CFG_sync(); + settings.showBatteryPercent = show; + CFG_sync(); } bool CFG_getMenuAnimations(void) { - return settings.showMenuAnimations; + return settings.showMenuAnimations; } void CFG_setMenuAnimations(bool show) { - settings.showMenuAnimations = show; - CFG_sync(); + settings.showMenuAnimations = show; + CFG_sync(); } bool CFG_getMenuTransitions(void) { - return settings.showMenuTransitions; + return settings.showMenuTransitions; } void CFG_setMenuTransitions(bool show) { - settings.showMenuTransitions = show; - CFG_sync(); + settings.showMenuTransitions = show; + CFG_sync(); } int CFG_getThumbnailRadius(void) { - return settings.thumbRadius; + return settings.thumbRadius; } void CFG_setThumbnailRadius(int radius) { - settings.thumbRadius = clamp(radius, 0, 24); - CFG_sync(); + settings.thumbRadius = clamp(radius, 0, 24); + CFG_sync(); } bool CFG_getShowRecents(void) { - return settings.showRecents; + return settings.showRecents; } void CFG_setShowRecents(bool show) { - settings.showRecents = show; - CFG_sync(); + settings.showRecents = show; + CFG_sync(); } bool CFG_getShowTools(void) { - return settings.showTools; + return settings.showTools; } void CFG_setShowTools(bool show) { - settings.showTools = show; - CFG_sync(); + settings.showTools = show; + CFG_sync(); } bool CFG_getShowGameArt(void) { - return settings.showGameArt; + return settings.showGameArt; } void CFG_setShowGameArt(bool show) { - settings.showGameArt = show; - CFG_sync(); + settings.showGameArt = show; + CFG_sync(); } bool CFG_getRomsUseFolderBackground(void) { - return settings.romsUseFolderBackground; + return settings.romsUseFolderBackground; } void CFG_setRomsUseFolderBackground(bool folder) { - settings.romsUseFolderBackground = folder; - CFG_sync(); + settings.romsUseFolderBackground = folder; + CFG_sync(); } int CFG_getGameSwitcherScaling(void) { - return settings.gameSwitcherScaling; + return settings.gameSwitcherScaling; } void CFG_setGameSwitcherScaling(int enumValue) { - settings.gameSwitcherScaling = clamp(enumValue, 0, GFX_SCALE_NUM_OPTIONS); - CFG_sync(); + settings.gameSwitcherScaling = clamp(enumValue, 0, GFX_SCALE_NUM_OPTIONS); + CFG_sync(); } bool CFG_getHaptics(void) { - return settings.haptics; + return settings.haptics; } void CFG_setHaptics(bool enable) { - settings.haptics = enable; - CFG_sync(); + settings.haptics = enable; + CFG_sync(); } int CFG_getSaveFormat(void) { - return settings.saveFormat; + return settings.saveFormat; } void CFG_setSaveFormat(int f) { - settings.saveFormat = f; - CFG_sync(); + settings.saveFormat = f; + CFG_sync(); } int CFG_getStateFormat(void) { - return settings.stateFormat; + return settings.stateFormat; } void CFG_setStateFormat(int f) { - settings.stateFormat = f; - CFG_sync(); + settings.stateFormat = f; + CFG_sync(); } bool CFG_getUseExtractedFileName(void) { - return settings.useExtractedFileName; + return settings.useExtractedFileName; } void CFG_setUseExtractedFileName(bool use) { - settings.useExtractedFileName = use; - CFG_sync(); + settings.useExtractedFileName = use; + CFG_sync(); } bool CFG_getMuteLEDs(void) { - return settings.muteLeds; + return settings.muteLeds; } void CFG_setMuteLEDs(bool on) { - settings.muteLeds = on; - CFG_sync(); + settings.muteLeds = on; + CFG_sync(); } double CFG_getGameArtWidth(void) { - return settings.gameArtWidth; + return settings.gameArtWidth; } void CFG_setGameArtWidth(double zeroToOne) { - settings.gameArtWidth = clampd(zeroToOne, 0.0, 1.0); - CFG_sync(); + settings.gameArtWidth = clampd(zeroToOne, 0.0, 1.0); + CFG_sync(); } bool CFG_getWifi(void) { - return settings.wifi; + return settings.wifi; } void CFG_setWifi(bool on) { - settings.wifi = on; - CFG_sync(); + settings.wifi = on; + CFG_sync(); } int CFG_getDefaultView(void) { - return settings.defaultView; + return settings.defaultView; } void CFG_setDefaultView(int view) { - settings.defaultView = view; - CFG_sync(); + settings.defaultView = view; + CFG_sync(); } bool CFG_getShowQuickswitcherUI(void) { - return settings.showQuickSwitcherUi; + return settings.showQuickSwitcherUi; } void CFG_setShowQuickswitcherUI(bool on) { - settings.showQuickSwitcherUi = on; - CFG_sync(); + settings.showQuickSwitcherUi = on; + CFG_sync(); } bool CFG_getWifiDiagnostics(void) { - return settings.wifiDiagnostics; + return settings.wifiDiagnostics; } void CFG_setWifiDiagnostics(bool on) { - settings.wifiDiagnostics = on; - CFG_sync(); + settings.wifiDiagnostics = on; + CFG_sync(); } bool CFG_getBluetooth(void) { - return settings.bluetooth; + return settings.bluetooth; } void CFG_setBluetooth(bool on) { - settings.bluetooth = on; - CFG_sync(); + settings.bluetooth = on; + CFG_sync(); } bool CFG_getBluetoothDiagnostics(void) { - return settings.bluetoothDiagnostics; + return settings.bluetoothDiagnostics; } void CFG_setBluetoothDiagnostics(bool on) { - settings.bluetoothDiagnostics = on; - CFG_sync(); + settings.bluetoothDiagnostics = on; + CFG_sync(); } int CFG_getBluetoothSamplingrateLimit(void) { - return settings.bluetoothSamplerateLimit; + return settings.bluetoothSamplerateLimit; } void CFG_setBluetoothSamplingrateLimit(int value) { - settings.bluetoothSamplerateLimit = value; - CFG_sync(); + settings.bluetoothSamplerateLimit = value; + CFG_sync(); } void CFG_get(const char *key, char *value) { - if (strcmp(key, "font") == 0) - { - sprintf(value, "%i", CFG_getFontId()); - } - else if (strcmp(key, "color1") == 0) - { - sprintf(value, "\"0x%06X\"", CFG_getColor(1)); - } - else if (strcmp(key, "color2") == 0) - { - sprintf(value, "\"0x%06X\"", CFG_getColor(2)); - } - else if (strcmp(key, "color3") == 0) - { - sprintf(value, "\"0x%06X\"", CFG_getColor(3)); - } - else if (strcmp(key, "color4") == 0) - { - sprintf(value, "\"0x%06X\"", CFG_getColor(4)); - } - else if (strcmp(key, "color5") == 0) - { - sprintf(value, "\"0x%06X\"", CFG_getColor(5)); - } - else if (strcmp(key, "color6") == 0) - { - sprintf(value, "\"0x%06X\"", CFG_getColor(6)); - } - else if (strcmp(key, "color7") == 0) - { - sprintf(value, "\"0x%06X\"", CFG_getColor(7)); - } - else if (strcmp(key, "radius") == 0) - { - sprintf(value, "%i", CFG_getThumbnailRadius()); - } - else if (strcmp(key, "showclock") == 0) - { - sprintf(value, "%i", CFG_getShowClock()); - } - else if (strcmp(key, "clock24h") == 0) - { - sprintf(value, "%i", CFG_getClock24H()); - } - else if (strcmp(key, "batteryperc") == 0) - { - sprintf(value, "%i", CFG_getShowBatteryPercent()); - } - else if (strcmp(key, "menuanim") == 0) - { - sprintf(value, "%i", CFG_getMenuAnimations()); - } - else if (strcmp(key, "menutransitions") == 0) - { - sprintf(value, "%i", CFG_getMenuTransitions()); - } - else if (strcmp(key, "recents") == 0) - { - sprintf(value, "%i", CFG_getShowRecents()); - } - else if (strcmp(key, "tools") == 0) - { - sprintf(value, "%i", CFG_getShowTools()); - } - else if (strcmp(key, "gameart") == 0) - { - sprintf(value, "%i", CFG_getShowGameArt()); - } - else if (strcmp(key, "showfoldernamesatroot") == 0) - { - sprintf(value, "%i", CFG_getShowFolderNamesAtRoot()); - } - else if (strcmp(key, "screentimeout") == 0) - { - sprintf(value, "%i", CFG_getScreenTimeoutSecs()); - } - else if (strcmp(key, "suspendTimeout") == 0) - { - sprintf(value, "%i", CFG_getSuspendTimeoutSecs()); - } - else if (strcmp(key, "switcherscale") == 0) - { - sprintf(value, "%i", CFG_getGameSwitcherScaling()); - } - else if (strcmp(key, "romfolderbg") == 0) - { - sprintf(value, "%i", CFG_getRomsUseFolderBackground()); - } - else if (strcmp(key, "saveFormat") == 0) - { - sprintf(value, "%i", CFG_getSaveFormat()); - } - else if (strcmp(key, "stateFormat") == 0) - { - sprintf(value, "%i", CFG_getStateFormat()); - } - else if (strcmp(key, "useExtractedFileName") == 0) - { - sprintf(value, "%i", CFG_getUseExtractedFileName()); - } - else if (strcmp(key, "muteLeds") == 0) - { - sprintf(value, "%i", CFG_getMuteLEDs()); - } - else if (strcmp(key, "artWidth") == 0) - { - sprintf(value, "%i", (int)(CFG_getGameArtWidth()) * 100); - } - else if (strcmp(key, "wifi") == 0) - { - sprintf(value, "%i", (int)(CFG_getWifi())); - } - else if (strcmp(key, "defaultView") == 0) - { - sprintf(value, "%i", (int)(CFG_getDefaultView())); - } - else if (strcmp(key, "quickSwitcherUi") == 0) - { - sprintf(value, "%i", (int)(CFG_getShowQuickswitcherUI())); - } - else if (strcmp(key, "wifiDiagnostics") == 0) - { - sprintf(value, "%i", (int)(CFG_getWifiDiagnostics())); - } - else if (strcmp(key, "bluetooth") == 0) - { - sprintf(value, "%i", (int)(CFG_getBluetooth())); - } - else if (strcmp(key, "btDiagnostics") == 0) - { - sprintf(value, "%i", (int)(CFG_getBluetoothDiagnostics())); - } - else if (strcmp(key, "btMaxRate") == 0) - { - sprintf(value, "%i", CFG_getBluetoothSamplingrateLimit()); - } - - // meta, not a real setting - else if (strcmp(key, "fontpath") == 0) - { - if (CFG_getFontId() == 1) - sprintf(value, "\"%s\"", RES_PATH "/font1.ttf"); - else - sprintf(value, "\"%s\"", RES_PATH "/font2.ttf"); - } - - else { - sprintf(value, ""); - } + if (strcmp(key, "font") == 0) { + sprintf(value, "%i", CFG_getFontId()); + } else if (strcmp(key, "color1") == 0) { + sprintf(value, "\"0x%06X\"", CFG_getColor(1)); + } else if (strcmp(key, "color2") == 0) { + sprintf(value, "\"0x%06X\"", CFG_getColor(2)); + } else if (strcmp(key, "color3") == 0) { + sprintf(value, "\"0x%06X\"", CFG_getColor(3)); + } else if (strcmp(key, "color4") == 0) { + sprintf(value, "\"0x%06X\"", CFG_getColor(4)); + } else if (strcmp(key, "color5") == 0) { + sprintf(value, "\"0x%06X\"", CFG_getColor(5)); + } else if (strcmp(key, "color6") == 0) { + sprintf(value, "\"0x%06X\"", CFG_getColor(6)); + } else if (strcmp(key, "color7") == 0) { + sprintf(value, "\"0x%06X\"", CFG_getColor(7)); + } else if (strcmp(key, "radius") == 0) { + sprintf(value, "%i", CFG_getThumbnailRadius()); + } else if (strcmp(key, "showclock") == 0) { + sprintf(value, "%i", CFG_getShowClock()); + } else if (strcmp(key, "clock24h") == 0) { + sprintf(value, "%i", CFG_getClock24H()); + } else if (strcmp(key, "batteryperc") == 0) { + sprintf(value, "%i", CFG_getShowBatteryPercent()); + } else if (strcmp(key, "menuanim") == 0) { + sprintf(value, "%i", CFG_getMenuAnimations()); + } else if (strcmp(key, "menutransitions") == 0) { + sprintf(value, "%i", CFG_getMenuTransitions()); + } else if (strcmp(key, "recents") == 0) { + sprintf(value, "%i", CFG_getShowRecents()); + } else if (strcmp(key, "tools") == 0) { + sprintf(value, "%i", CFG_getShowTools()); + } else if (strcmp(key, "gameart") == 0) { + sprintf(value, "%i", CFG_getShowGameArt()); + } else if (strcmp(key, "showfoldernamesatroot") == 0) { + sprintf(value, "%i", CFG_getShowFolderNamesAtRoot()); + } else if (strcmp(key, "screentimeout") == 0) { + sprintf(value, "%i", CFG_getScreenTimeoutSecs()); + } else if (strcmp(key, "suspendTimeout") == 0) { + sprintf(value, "%i", CFG_getSuspendTimeoutSecs()); + } else if (strcmp(key, "switcherscale") == 0) { + sprintf(value, "%i", CFG_getGameSwitcherScaling()); + } else if (strcmp(key, "romfolderbg") == 0) { + sprintf(value, "%i", CFG_getRomsUseFolderBackground()); + } else if (strcmp(key, "saveFormat") == 0) { + sprintf(value, "%i", CFG_getSaveFormat()); + } else if (strcmp(key, "stateFormat") == 0) { + sprintf(value, "%i", CFG_getStateFormat()); + } else if (strcmp(key, "useExtractedFileName") == 0) { + sprintf(value, "%i", CFG_getUseExtractedFileName()); + } else if (strcmp(key, "muteLeds") == 0) { + sprintf(value, "%i", CFG_getMuteLEDs()); + } else if (strcmp(key, "artWidth") == 0) { + sprintf(value, "%i", (int)(CFG_getGameArtWidth()) * 100); + } else if (strcmp(key, "wifi") == 0) { + sprintf(value, "%i", (int)(CFG_getWifi())); + } else if (strcmp(key, "defaultView") == 0) { + sprintf(value, "%i", (int)(CFG_getDefaultView())); + } else if (strcmp(key, "quickSwitcherUi") == 0) { + sprintf(value, "%i", (int)(CFG_getShowQuickswitcherUI())); + } else if (strcmp(key, "wifiDiagnostics") == 0) { + sprintf(value, "%i", (int)(CFG_getWifiDiagnostics())); + } else if (strcmp(key, "bluetooth") == 0) { + sprintf(value, "%i", (int)(CFG_getBluetooth())); + } else if (strcmp(key, "btDiagnostics") == 0) { + sprintf(value, "%i", (int)(CFG_getBluetoothDiagnostics())); + } else if (strcmp(key, "btMaxRate") == 0) { + sprintf(value, "%i", CFG_getBluetoothSamplingrateLimit()); + } + + // meta, not a real setting + else if (strcmp(key, "fontpath") == 0) { + if (CFG_getFontId() == 1) + sprintf(value, "\"%s\"", RES_PATH "/font1.ttf"); + else + sprintf(value, "\"%s\"", RES_PATH "/font2.ttf"); + } + + else { + sprintf(value, ""); + } } void CFG_sync(void) { - // write to file - char settingsPath[MAX_PATH]; - sprintf(settingsPath, "%s/minuisettings.txt", getenv("SHARED_USERDATA_PATH")); - FILE *file = fopen(settingsPath, "w"); - if (file == NULL) - { - printf("[CFG] Unable to open settings file, cant write\n"); - return; - } - - fprintf(file, "font=%i\n", settings.font); - fprintf(file, "color1=0x%06X\n", settings.color1_255); - fprintf(file, "color2=0x%06X\n", settings.color2_255); - fprintf(file, "color3=0x%06X\n", settings.color3_255); - fprintf(file, "color4=0x%06X\n", settings.color4_255); - fprintf(file, "color5=0x%06X\n", settings.color5_255); - fprintf(file, "color6=0x%06X\n", settings.color6_255); - fprintf(file, "color7=0x%06X\n", settings.color7_255); - fprintf(file, "radius=%i\n", settings.thumbRadius); - fprintf(file, "showclock=%i\n", settings.showClock); - fprintf(file, "clock24h=%i\n", settings.clock24h); - fprintf(file, "batteryperc=%i\n", settings.showBatteryPercent); - fprintf(file, "menuanim=%i\n", settings.showMenuAnimations); - fprintf(file, "menutransitions=%i\n", settings.showMenuTransitions); - fprintf(file, "recents=%i\n", settings.showRecents); - fprintf(file, "tools=%i\n", settings.showTools); - fprintf(file, "gameart=%i\n", settings.showGameArt); - fprintf(file, "showfoldernamesatroot=%i\n", settings.showFolderNamesAtRoot); - fprintf(file, "screentimeout=%i\n", settings.screenTimeoutSecs); - fprintf(file, "suspendTimeout=%i\n", settings.suspendTimeoutSecs); - fprintf(file, "switcherscale=%i\n", settings.gameSwitcherScaling); - fprintf(file, "haptics=%i\n", settings.haptics); - fprintf(file, "romfolderbg=%i\n", settings.romsUseFolderBackground); - fprintf(file, "saveFormat=%i\n", settings.saveFormat); - fprintf(file, "stateFormat=%i\n", settings.stateFormat); - fprintf(file, "useExtractedFileName=%i\n", settings.useExtractedFileName); - fprintf(file, "muteLeds=%i\n", settings.muteLeds); - fprintf(file, "artWidth=%i\n", (int)(settings.gameArtWidth * 100)); - fprintf(file, "wifi=%i\n", settings.wifi); - fprintf(file, "defaultView=%i\n", settings.defaultView); - fprintf(file, "quickSwitcherUi=%i\n", settings.showQuickSwitcherUi); - fprintf(file, "wifiDiagnostics=%i\n", settings.wifiDiagnostics); - fprintf(file, "bluetooth=%i\n", settings.bluetooth); - fprintf(file, "btDiagnostics=%i\n", settings.bluetoothDiagnostics); - fprintf(file, "btMaxRate=%i\n", settings.bluetoothSamplerateLimit); - - fclose(file); + // write to file + char settingsPath[MAX_PATH]; + sprintf(settingsPath, "%s/minuisettings.txt", getenv("SHARED_USERDATA_PATH")); + FILE *file = fopen(settingsPath, "w"); + if (file == NULL) { + printf("[CFG] Unable to open settings file, cant write\n"); + return; + } + + fprintf(file, "font=%i\n", settings.font); + fprintf(file, "color1=0x%06X\n", settings.color1_255); + fprintf(file, "color2=0x%06X\n", settings.color2_255); + fprintf(file, "color3=0x%06X\n", settings.color3_255); + fprintf(file, "color4=0x%06X\n", settings.color4_255); + fprintf(file, "color5=0x%06X\n", settings.color5_255); + fprintf(file, "color6=0x%06X\n", settings.color6_255); + fprintf(file, "color7=0x%06X\n", settings.color7_255); + fprintf(file, "radius=%i\n", settings.thumbRadius); + fprintf(file, "showclock=%i\n", settings.showClock); + fprintf(file, "clock24h=%i\n", settings.clock24h); + fprintf(file, "batteryperc=%i\n", settings.showBatteryPercent); + fprintf(file, "menuanim=%i\n", settings.showMenuAnimations); + fprintf(file, "menutransitions=%i\n", settings.showMenuTransitions); + fprintf(file, "recents=%i\n", settings.showRecents); + fprintf(file, "tools=%i\n", settings.showTools); + fprintf(file, "gameart=%i\n", settings.showGameArt); + fprintf(file, "showfoldernamesatroot=%i\n", settings.showFolderNamesAtRoot); + fprintf(file, "screentimeout=%i\n", settings.screenTimeoutSecs); + fprintf(file, "suspendTimeout=%i\n", settings.suspendTimeoutSecs); + fprintf(file, "switcherscale=%i\n", settings.gameSwitcherScaling); + fprintf(file, "haptics=%i\n", settings.haptics); + fprintf(file, "romfolderbg=%i\n", settings.romsUseFolderBackground); + fprintf(file, "saveFormat=%i\n", settings.saveFormat); + fprintf(file, "stateFormat=%i\n", settings.stateFormat); + fprintf(file, "useExtractedFileName=%i\n", settings.useExtractedFileName); + fprintf(file, "muteLeds=%i\n", settings.muteLeds); + fprintf(file, "artWidth=%i\n", (int)(settings.gameArtWidth * 100)); + fprintf(file, "wifi=%i\n", settings.wifi); + fprintf(file, "defaultView=%i\n", settings.defaultView); + fprintf(file, "quickSwitcherUi=%i\n", settings.showQuickSwitcherUi); + fprintf(file, "wifiDiagnostics=%i\n", settings.wifiDiagnostics); + fprintf(file, "bluetooth=%i\n", settings.bluetooth); + fprintf(file, "btDiagnostics=%i\n", settings.bluetoothDiagnostics); + fprintf(file, "btMaxRate=%i\n", settings.bluetoothSamplerateLimit); + + fclose(file); } void CFG_print(void) { - printf("{\n"); - printf("\t\"font\": %i,\n", settings.font); - printf("\t\"color1\": \"0x%06X\",\n", settings.color1_255); - printf("\t\"color2\": \"0x%06X\",\n", settings.color2_255); - printf("\t\"color3\": \"0x%06X\",\n", settings.color3_255); - printf("\t\"color4\": \"0x%06X\",\n", settings.color4_255); - printf("\t\"color5\": \"0x%06X\",\n", settings.color5_255); - printf("\t\"color6\": \"0x%06X\",\n", settings.color6_255); - printf("\t\"color7\": \"0x%06X\",\n", settings.color7_255); - printf("\t\"radius\": %i,\n", settings.thumbRadius); - printf("\t\"showclock\": %i,\n", settings.showClock); - printf("\t\"clock24h\": %i,\n", settings.clock24h); - printf("\t\"batteryperc\": %i,\n", settings.showBatteryPercent); - printf("\t\"menuanim\": %i,\n", settings.showMenuAnimations); - printf("\t\"menutransitions\": %i,\n", settings.showMenuTransitions); - printf("\t\"recents\": %i,\n", settings.showRecents); - printf("\t\"tools\": %i,\n", settings.showTools); - printf("\t\"gameart\": %i,\n", settings.showGameArt); + printf("{\n"); + printf("\t\"font\": %i,\n", settings.font); + printf("\t\"color1\": \"0x%06X\",\n", settings.color1_255); + printf("\t\"color2\": \"0x%06X\",\n", settings.color2_255); + printf("\t\"color3\": \"0x%06X\",\n", settings.color3_255); + printf("\t\"color4\": \"0x%06X\",\n", settings.color4_255); + printf("\t\"color5\": \"0x%06X\",\n", settings.color5_255); + printf("\t\"color6\": \"0x%06X\",\n", settings.color6_255); + printf("\t\"color7\": \"0x%06X\",\n", settings.color7_255); + printf("\t\"radius\": %i,\n", settings.thumbRadius); + printf("\t\"showclock\": %i,\n", settings.showClock); + printf("\t\"clock24h\": %i,\n", settings.clock24h); + printf("\t\"batteryperc\": %i,\n", settings.showBatteryPercent); + printf("\t\"menuanim\": %i,\n", settings.showMenuAnimations); + printf("\t\"menutransitions\": %i,\n", settings.showMenuTransitions); + printf("\t\"recents\": %i,\n", settings.showRecents); + printf("\t\"tools\": %i,\n", settings.showTools); + printf("\t\"gameart\": %i,\n", settings.showGameArt); printf("\t\"showfoldernamesatroot\": %i,\n", settings.showFolderNamesAtRoot); - printf("\t\"screentimeout\": %i,\n", settings.screenTimeoutSecs); - printf("\t\"suspendTimeout\": %i,\n", settings.suspendTimeoutSecs); - printf("\t\"switcherscale\": %i,\n", settings.gameSwitcherScaling); - printf("\t\"haptics\": %i,\n", settings.haptics); - printf("\t\"romfolderbg\": %i,\n", settings.romsUseFolderBackground); - printf("\t\"saveFormat\": %i,\n", settings.saveFormat); - printf("\t\"stateFormat\": %i,\n", settings.stateFormat); - printf("\t\"useExtractedFileName\": %i,\n", settings.useExtractedFileName); - printf("\t\"muteLeds\": %i,\n", settings.muteLeds); - printf("\t\"artWidth\": %i,\n", (int)(settings.gameArtWidth * 100)); - printf("\t\"wifi\": %i,\n", settings.wifi); - printf("\t\"defaultView\": %i,\n", settings.defaultView); - printf("\t\"quickSwitcherUi\": %i,\n", settings.showQuickSwitcherUi); - printf("\t\"wifiDiagnostics\": %i,\n", settings.wifiDiagnostics); - printf("\t\"bluetooth\": %i,\n", settings.bluetooth); - printf("\t\"btDiagnostics\": %i,\n", settings.bluetoothDiagnostics); - printf("\t\"btMaxRate\": %i,\n", settings.bluetoothSamplerateLimit); - - // meta, not a real setting - if (settings.font == 1) - printf("\t\"fontpath\": \"%s\"\n", RES_PATH "/font1.ttf"); - else - printf("\t\"fontpath\": \"%s\"\n", RES_PATH "/font2.ttf"); - - printf("}\n"); + printf("\t\"screentimeout\": %i,\n", settings.screenTimeoutSecs); + printf("\t\"suspendTimeout\": %i,\n", settings.suspendTimeoutSecs); + printf("\t\"switcherscale\": %i,\n", settings.gameSwitcherScaling); + printf("\t\"haptics\": %i,\n", settings.haptics); + printf("\t\"romfolderbg\": %i,\n", settings.romsUseFolderBackground); + printf("\t\"saveFormat\": %i,\n", settings.saveFormat); + printf("\t\"stateFormat\": %i,\n", settings.stateFormat); + printf("\t\"useExtractedFileName\": %i,\n", settings.useExtractedFileName); + printf("\t\"muteLeds\": %i,\n", settings.muteLeds); + printf("\t\"artWidth\": %i,\n", (int)(settings.gameArtWidth * 100)); + printf("\t\"wifi\": %i,\n", settings.wifi); + printf("\t\"defaultView\": %i,\n", settings.defaultView); + printf("\t\"quickSwitcherUi\": %i,\n", settings.showQuickSwitcherUi); + printf("\t\"wifiDiagnostics\": %i,\n", settings.wifiDiagnostics); + printf("\t\"bluetooth\": %i,\n", settings.bluetooth); + printf("\t\"btDiagnostics\": %i,\n", settings.bluetoothDiagnostics); + printf("\t\"btMaxRate\": %i,\n", settings.bluetoothSamplerateLimit); + + // meta, not a real setting + if (settings.font == 1) + printf("\t\"fontpath\": \"%s\"\n", RES_PATH "/font1.ttf"); + else + printf("\t\"fontpath\": \"%s\"\n", RES_PATH "/font2.ttf"); + + printf("}\n"); } void CFG_quit(void) { - CFG_sync(); + CFG_sync(); } \ No newline at end of file diff --git a/workspace/all/common/config.h b/workspace/all/common/config.h index 64d663cbc..ca8ca2df9 100644 --- a/workspace/all/common/config.h +++ b/workspace/all/common/config.h @@ -16,32 +16,30 @@ extern uint32_t THEME_COLOR7_255; // Read-only interface for minui.c usage // Read/Write interface for settings.cpp usage -typedef int (*FontLoad_callback_t)(const char* path); +typedef int (*FontLoad_callback_t)(const char *path); typedef int (*ColorSet_callback_t)(void); -enum -{ +enum { // MinUI: Game.gba.sav SAVE_FORMAT_SAV, - //Retroarch: Game.srm + // Retroarch: Game.srm SAVE_FORMAT_SRM, // Generic: Game.sav SAVE_FORMAT_GEN, - //Retroarch: Game.srm + // Retroarch: Game.srm SAVE_FORMAT_SRM_UNCOMPRESSED }; -enum -{ +enum { // MinUI: Game.st0 STATE_FORMAT_SAV, - //Retroarch-ish: Game.state. (a typo, but keeping it to avoid a breaking change) + // Retroarch-ish: Game.state. (a typo, but keeping it to avoid a breaking change) STATE_FORMAT_SRM_EXTRADOT, - //Retroarch-ish: Game.state. (a typo, but keeping it to avoid a breaking change) + // Retroarch-ish: Game.state. (a typo, but keeping it to avoid a breaking change) STATE_FORMAT_SRM_UNCOMRESSED_EXTRADOT, - //Retroarch: Game.state + // Retroarch: Game.state STATE_FORMAT_SRM, - //Retroarch: Game.state + // Retroarch: Game.state STATE_FORMAT_SRM_UNCOMRESSED }; @@ -55,8 +53,7 @@ enum { SCREEN_OFF }; -typedef struct -{ +typedef struct { // Theme int font; uint32_t color1_255; // not screen mapped @@ -71,12 +68,12 @@ typedef struct double gameArtWidth; // [0,1] -> 0-100% of screen width // font loading/unloading callback - FontLoad_callback_t onFontChange; + FontLoad_callback_t onFontChange; - // color update callback - ColorSet_callback_t onColorSet; + // color update callback + ColorSet_callback_t onColorSet; - // UI + // UI bool showClock; bool clock24h; bool showBatteryPercent; @@ -114,7 +111,7 @@ typedef struct } NextUISettings; -#define CFG_DEFAULT_FONT_ID 1 // Next +#define CFG_DEFAULT_FONT_ID 1 // Next #define CFG_DEFAULT_COLOR1 0xffffffU #define CFG_DEFAULT_COLOR2 0x9b2257U #define CFG_DEFAULT_COLOR3 0x1e2329U @@ -152,7 +149,7 @@ typedef struct void CFG_init(FontLoad_callback_t fontCallback, ColorSet_callback_t ccb); void CFG_print(void); -void CFG_get(const char *key, char * value); +void CFG_get(const char *key, char *value); // void CFG_defaults(NextUISettings*); // The font id to use as the UI font. // 0 - Default MinUI font diff --git a/workspace/all/common/defines.h b/workspace/all/common/defines.h index ba5bf08f0..5991e45d5 100644 --- a/workspace/all/common/defines.h +++ b/workspace/all/common/defines.h @@ -3,12 +3,12 @@ #include "platform.h" -#define VOLUME_MIN 0 -#define VOLUME_MAX 20 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 10 -#define COLORTEMP_MIN 0 -#define COLORTEMP_MAX 40 +#define VOLUME_MIN 0 +#define VOLUME_MAX 20 +#define BRIGHTNESS_MIN 0 +#define BRIGHTNESS_MAX 10 +#define COLORTEMP_MIN 0 +#define COLORTEMP_MAX 40 #define STR_MAX 256 #define MAX_PATH 512 @@ -36,21 +36,45 @@ #define RESUME_SLOT_PATH "/tmp/resume_slot.txt" #define NOUI_PATH "/tmp/noui" -#define TRIAD_WHITE 0xff,0xff,0xff -#define TRIAD_BLACK 0x00,0x00,0x00 -#define TRIAD_LIGHT_GRAY 0x7f,0x7f,0x7f -#define TRIAD_GRAY 0x99,0x99,0x99 -#define TRIAD_DARK_GRAY 0x26,0x26,0x26 - -#define TRIAD_LIGHT_TEXT 0xcc,0xcc,0xcc -#define TRIAD_DARK_TEXT 0x66,0x66,0x66 - -#define COLOR_WHITE (SDL_Color){TRIAD_WHITE} -#define COLOR_GRAY (SDL_Color){TRIAD_GRAY} -#define COLOR_BLACK (SDL_Color){TRIAD_BLACK} -#define COLOR_LIGHT_TEXT (SDL_Color){TRIAD_LIGHT_TEXT} -#define COLOR_DARK_TEXT (SDL_Color){TRIAD_DARK_TEXT} -#define COLOR_BUTTON_TEXT (SDL_Color){TRIAD_GRAY} +#define TRIAD_WHITE 0xff, 0xff, 0xff +#define TRIAD_BLACK 0x00, 0x00, 0x00 +#define TRIAD_LIGHT_GRAY 0x7f, 0x7f, 0x7f +#define TRIAD_GRAY 0x99, 0x99, 0x99 +#define TRIAD_DARK_GRAY 0x26, 0x26, 0x26 + +#define TRIAD_LIGHT_TEXT 0xcc, 0xcc, 0xcc +#define TRIAD_DARK_TEXT 0x66, 0x66, 0x66 + +#define COLOR_WHITE \ + (SDL_Color) \ + { \ + TRIAD_WHITE \ + } +#define COLOR_GRAY \ + (SDL_Color) \ + { \ + TRIAD_GRAY \ + } +#define COLOR_BLACK \ + (SDL_Color) \ + { \ + TRIAD_BLACK \ + } +#define COLOR_LIGHT_TEXT \ + (SDL_Color) \ + { \ + TRIAD_LIGHT_TEXT \ + } +#define COLOR_DARK_TEXT \ + (SDL_Color) \ + { \ + TRIAD_DARK_TEXT \ + } +#define COLOR_BUTTON_TEXT \ + (SDL_Color) \ + { \ + TRIAD_GRAY \ + } // all before scale #define PILL_SIZE 30 @@ -72,11 +96,11 @@ #define PADDING 10 // PILL_SIZE / 3 (or non-integer part of the previous calculatiom divided by three) #endif -#define FONT_LARGE 16 // menu -#define FONT_MEDIUM 14 // single char button label -#define FONT_SMALL 12 // button hint -#define FONT_TINY 10 // multi char button label -#define FONT_MICRO 7 // icon overlay text +#define FONT_LARGE 16 // menu +#define FONT_MEDIUM 14 // single char button label +#define FONT_SMALL 12 // button hint +#define FONT_TINY 10 // multi char button label +#define FONT_MICRO 7 // icon overlay text #ifndef MAX_LIGHTS #define MAX_LIGHTS 0 @@ -84,12 +108,11 @@ #ifndef MAXSHADERS #define MAXSHADERS 3 #endif -enum -{ +enum { GFX_SCALE_FULLSCREEN = 0, GFX_SCALE_FIT, GFX_SCALE_FILL, - GFX_SCALE_NUM_OPTIONS // do not use + GFX_SCALE_NUM_OPTIONS // do not use }; /////////////////////////////// @@ -99,26 +122,26 @@ enum #define MAX(a, b) (a) > (b) ? (a) : (b) #define MIN(a, b) (a) < (b) ? (a) : (b) -#define CEIL_DIV(a,b) ((a) + (b) - 1) / (b) +#define CEIL_DIV(a, b) ((a) + (b) - 1) / (b) -#define SCALE1(a) ((a)*FIXED_SCALE) -#define SCALE2(a,b) ((a)*FIXED_SCALE),((b)*FIXED_SCALE) -#define SCALE3(a,b,c) ((a)*FIXED_SCALE),((b)*FIXED_SCALE),((c)*FIXED_SCALE) -#define SCALE4(a,b,c,d) ((a)*FIXED_SCALE),((b)*FIXED_SCALE),((c)*FIXED_SCALE),((d)*FIXED_SCALE) +#define SCALE1(a) ((a) * FIXED_SCALE) +#define SCALE2(a, b) ((a) * FIXED_SCALE), ((b) * FIXED_SCALE) +#define SCALE3(a, b, c) ((a) * FIXED_SCALE), ((b) * FIXED_SCALE), ((c) * FIXED_SCALE) +#define SCALE4(a, b, c, d) ((a) * FIXED_SCALE), ((b) * FIXED_SCALE), ((c) * FIXED_SCALE), ((d) * FIXED_SCALE) /////////////////////////////// -#define HAS_POWER_BUTTON (BUTTON_POWER!=BUTTON_NA||CODE_POWER!=CODE_NA||JOY_POWER!=JOY_NA) -#define HAS_POWEROFF_BUTTON (BUTTON_POWEROFF!=BUTTON_NA) -#define HAS_MENU_BUTTON (BUTTON_MENU!=BUTTON_NA||CODE_MENU!=CODE_NA||JOY_MENU!=JOY_NA) -#define HAS_SKINNY_SCREEN (FIXED_WIDTH<320) +#define HAS_POWER_BUTTON (BUTTON_POWER != BUTTON_NA || CODE_POWER != CODE_NA || JOY_POWER != JOY_NA) +#define HAS_POWEROFF_BUTTON (BUTTON_POWEROFF != BUTTON_NA) +#define HAS_MENU_BUTTON (BUTTON_MENU != BUTTON_NA || CODE_MENU != CODE_NA || JOY_MENU != JOY_NA) +#define HAS_SKINNY_SCREEN (FIXED_WIDTH < 320) /////////////////////////////// -#define BUTTON_NA -1 -#define CODE_NA -1 -#define JOY_NA -1 -#define AXIS_NA -1 +#define BUTTON_NA -1 +#define CODE_NA -1 +#define JOY_NA -1 +#define AXIS_NA -1 #ifndef BUTTON_POWEROFF #define BUTTON_POWEROFF BUTTON_NA @@ -142,22 +165,22 @@ enum #endif #ifndef AXIS_L2 -#define AXIS_L2 AXIS_NA -#define AXIS_R2 AXIS_NA -#endif +#define AXIS_L2 AXIS_NA +#define AXIS_R2 AXIS_NA +#endif #ifndef AXIS_LX -#define AXIS_LX AXIS_NA -#define AXIS_LY AXIS_NA -#define AXIS_RX AXIS_NA -#define AXIS_RY AXIS_NA -#endif +#define AXIS_LX AXIS_NA +#define AXIS_LY AXIS_NA +#define AXIS_RX AXIS_NA +#define AXIS_RY AXIS_NA +#endif #ifndef HAS_HDMI -#define HDMI_WIDTH FIXED_WIDTH -#define HDMI_HEIGHT FIXED_HEIGHT -#define HDMI_PITCH FIXED_PITCH -#define HDMI_SIZE FIXED_SIZE +#define HDMI_WIDTH FIXED_WIDTH +#define HDMI_HEIGHT FIXED_HEIGHT +#define HDMI_PITCH FIXED_PITCH +#define HDMI_SIZE FIXED_SIZE #endif #ifndef BTN_A // prevent collisions with input.h in keymon @@ -183,7 +206,7 @@ enum { BTN_ID_MENU, BTN_ID_PLUS, BTN_ID_MINUS, - BTN_ID_POWER, + BTN_ID_POWER, BTN_ID_POWEROFF, BTN_ID_ANALOG_UP, @@ -194,38 +217,38 @@ enum { BTN_ID_COUNT, }; enum { - BTN_NONE = 0, - BTN_DPAD_UP = 1 << BTN_ID_DPAD_UP, - BTN_DPAD_DOWN = 1 << BTN_ID_DPAD_DOWN, - BTN_DPAD_LEFT = 1 << BTN_ID_DPAD_LEFT, - BTN_DPAD_RIGHT = 1 << BTN_ID_DPAD_RIGHT, - BTN_A = 1 << BTN_ID_A, - BTN_B = 1 << BTN_ID_B, - BTN_X = 1 << BTN_ID_X, - BTN_Y = 1 << BTN_ID_Y, - BTN_START = 1 << BTN_ID_START, - BTN_SELECT = 1 << BTN_ID_SELECT, - BTN_L1 = 1 << BTN_ID_L1, - BTN_R1 = 1 << BTN_ID_R1, - BTN_L2 = 1 << BTN_ID_L2, - BTN_R2 = 1 << BTN_ID_R2, - BTN_L3 = 1 << BTN_ID_L3, - BTN_R3 = 1 << BTN_ID_R3, - BTN_MENU = 1 << BTN_ID_MENU, - BTN_PLUS = 1 << BTN_ID_PLUS, - BTN_MINUS = 1 << BTN_ID_MINUS, - BTN_POWER = 1 << BTN_ID_POWER, - BTN_POWEROFF = 1 << BTN_ID_POWEROFF, - - BTN_ANALOG_UP = 1 << BTN_ID_ANALOG_UP, - BTN_ANALOG_DOWN = 1 << BTN_ID_ANALOG_DOWN, - BTN_ANALOG_LEFT = 1 << BTN_ID_ANALOG_LEFT, - BTN_ANALOG_RIGHT= 1 << BTN_ID_ANALOG_RIGHT, - - BTN_UP = BTN_DPAD_UP | BTN_ANALOG_UP, - BTN_DOWN = BTN_DPAD_DOWN | BTN_ANALOG_DOWN, - BTN_LEFT = BTN_DPAD_LEFT | BTN_ANALOG_LEFT, - BTN_RIGHT = BTN_DPAD_RIGHT | BTN_ANALOG_RIGHT, + BTN_NONE = 0, + BTN_DPAD_UP = 1 << BTN_ID_DPAD_UP, + BTN_DPAD_DOWN = 1 << BTN_ID_DPAD_DOWN, + BTN_DPAD_LEFT = 1 << BTN_ID_DPAD_LEFT, + BTN_DPAD_RIGHT = 1 << BTN_ID_DPAD_RIGHT, + BTN_A = 1 << BTN_ID_A, + BTN_B = 1 << BTN_ID_B, + BTN_X = 1 << BTN_ID_X, + BTN_Y = 1 << BTN_ID_Y, + BTN_START = 1 << BTN_ID_START, + BTN_SELECT = 1 << BTN_ID_SELECT, + BTN_L1 = 1 << BTN_ID_L1, + BTN_R1 = 1 << BTN_ID_R1, + BTN_L2 = 1 << BTN_ID_L2, + BTN_R2 = 1 << BTN_ID_R2, + BTN_L3 = 1 << BTN_ID_L3, + BTN_R3 = 1 << BTN_ID_R3, + BTN_MENU = 1 << BTN_ID_MENU, + BTN_PLUS = 1 << BTN_ID_PLUS, + BTN_MINUS = 1 << BTN_ID_MINUS, + BTN_POWER = 1 << BTN_ID_POWER, + BTN_POWEROFF = 1 << BTN_ID_POWEROFF, + + BTN_ANALOG_UP = 1 << BTN_ID_ANALOG_UP, + BTN_ANALOG_DOWN = 1 << BTN_ID_ANALOG_DOWN, + BTN_ANALOG_LEFT = 1 << BTN_ID_ANALOG_LEFT, + BTN_ANALOG_RIGHT = 1 << BTN_ID_ANALOG_RIGHT, + + BTN_UP = BTN_DPAD_UP | BTN_ANALOG_UP, + BTN_DOWN = BTN_DPAD_DOWN | BTN_ANALOG_DOWN, + BTN_LEFT = BTN_DPAD_LEFT | BTN_ANALOG_LEFT, + BTN_RIGHT = BTN_DPAD_RIGHT | BTN_ANALOG_RIGHT, }; #endif diff --git a/workspace/all/common/scaler.c b/workspace/all/common/scaler.c index 1ca94ef19..4f6ffbc63 100644 --- a/workspace/all/common/scaler.c +++ b/workspace/all/common/scaler.c @@ -21,2954 +21,3781 @@ // if odd#, then handled by the C scaler // -static void dummy(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) {} +static void dummy(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ +} -// +// // C scalers for Trimui Model S and GKD Pixel // -void scale1x_c16to32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t x, dx, pix, dpix1, dpix2, swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } swl*=2; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x<(sw/2); x++, dx+=2) { +void scale1x_c16to32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t x, dx, pix, dpix1, dpix2, swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + swl *= 2; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < (sw / 2); x++, dx += 2) { pix = s[x]; dpix1 = 0xFF000000 | ((pix & 0xF800) << 8) | ((pix & 0x07E0) << 5) | ((pix & 0x001F) << 3); - dpix2 = 0xFF000000 | ((pix & 0xF8000000) >> 8) | ((pix & 0x07E00000) >> 11) | ((pix & 0x001F0000) >> 13); d[dx ] = dpix1; d[dx+1] = dpix1; - d[dx ] = dpix1; d[dx+1] = dpix2; + dpix2 = 0xFF000000 | ((pix & 0xF8000000) >> 8) | ((pix & 0x07E00000) >> 11) | ((pix & 0x001F0000) >> 13); + d[dx] = dpix1; + d[dx + 1] = dpix1; + d[dx] = dpix1; + d[dx + 1] = dpix2; } - if (sw&1) { - uint16_t *s16 = (uint16_t*)s; - uint16_t pix16 = s16[x*2]; + if (sw & 1) { + uint16_t *s16 = (uint16_t *)s; + uint16_t pix16 = s16[x * 2]; pix16 = 0xFF000000 | ((pix16 & 0xF800) << 8) | ((pix16 & 0x07E0) << 5) | ((pix16 & 0x001F) << 3); - d[dx ] = pix16; d[dx+1] = pix16; + d[dx] = pix16; + d[dx + 1] = pix16; } - dst = (uint8_t*)dst+dp; + dst = (uint8_t *)dst + dp; } } -void scale2x_c16to32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t x, dx, pix, dpix1, dpix2, swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } swl*=2; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x<(sw/2); x++, dx+=4) { +void scale2x_c16to32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t x, dx, pix, dpix1, dpix2, swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + swl *= 2; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < (sw / 2); x++, dx += 4) { pix = s[x]; dpix1 = 0xFF000000 | ((pix & 0xF800) << 8) | ((pix & 0x07E0) << 5) | ((pix & 0x001F) << 3); - dpix2 = 0xFF000000 | ((pix & 0xF8000000) >> 8) | ((pix & 0x07E00000) >> 11) | ((pix & 0x001F0000) >> 13); d[dx ] = dpix1; d[dx+1] = dpix1; - d[dx+2] = dpix2; d[dx+3] = dpix2; + dpix2 = 0xFF000000 | ((pix & 0xF8000000) >> 8) | ((pix & 0x07E00000) >> 11) | ((pix & 0x001F0000) >> 13); + d[dx] = dpix1; + d[dx + 1] = dpix1; + d[dx + 2] = dpix2; + d[dx + 3] = dpix2; } - if (sw&1) { - uint16_t *s16 = (uint16_t*)s; - uint16_t pix16 = s16[x*2]; + if (sw & 1) { + uint16_t *s16 = (uint16_t *)s; + uint16_t pix16 = s16[x * 2]; pix16 = 0xFF000000 | ((pix16 & 0xF800) << 8) | ((pix16 & 0x07E0) << 5) | ((pix16 & 0x001F) << 3); - d[dx ] = pix16; d[dx+1] = pix16; + d[dx] = pix16; + d[dx + 1] = pix16; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - memcpy(dst, dstsrc, swl); dst = (uint8_t*)dst+dp; + void *__restrict dstsrc = dst; + dst = (uint8_t *)dst + dp; + memcpy(dst, dstsrc, swl); + dst = (uint8_t *)dst + dp; } } // // C scalers // -void scale1x_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*1; } - if ((ymul == 1)&&(swl == sp)&&(sp == dp)) memcpy(dst, src, sp*sh); +void scale1x_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 1; + } + if ((ymul == 1) && (swl == sp) && (sp == dp)) + memcpy(dst, src, sp * sh); else { - if (swl>dp) swl = dp; - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - for (uint32_t i=ymul; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, src, swl); + if (swl > dp) + swl = dp; + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + for (uint32_t i = ymul; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, src, swl); } } } -void scale1x1_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale1x2_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale1x3_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale1x4_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); } +void scale1x1_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale1x2_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale1x3_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale1x4_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} -void scale1x_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*1; } - if ((ymul == 1)&&(swl == sp)&&(sp == dp)) memcpy(dst, src, sp*sh); +void scale1x_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 1; + } + if ((ymul == 1) && (swl == sp) && (sp == dp)) + memcpy(dst, src, sp * sh); else { - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - for (uint32_t i=ymul; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, src, swl); + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + for (uint32_t i = ymul; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, src, swl); } } } -void scale1x1_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale1x2_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale1x3_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale1x4_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); } - -void scale2x_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, dpix1, dpix2, swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } swl*=2; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x<(sw/2); x++, dx+=2) { +void scale1x1_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale1x2_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale1x3_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale1x4_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale1x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} + +void scale2x_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, dpix1, dpix2, swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + swl *= 2; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < (sw / 2); x++, dx += 2) { pix = s[x]; - dpix1=(pix & 0x0000FFFF)|(pix<<16); - dpix2=(pix & 0xFFFF0000)|(pix>>16); - d[dx] = dpix1; d[dx+1] = dpix2; + dpix1 = (pix & 0x0000FFFF) | (pix << 16); + dpix2 = (pix & 0xFFFF0000) | (pix >> 16); + d[dx] = dpix1; + d[dx + 1] = dpix2; } - if (sw&1) { - uint16_t *s16 = (uint16_t*)s; - uint16_t pix16 = s16[x*2]; - d[dx] = pix16|(pix16<<16); + if (sw & 1) { + uint16_t *s16 = (uint16_t *)s; + uint16_t pix16 = s16[x * 2]; + d[dx] = pix16 | (pix16 << 16); } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale2x1_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale2x2_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale2x3_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale2x4_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); } - -void scale2x_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } swl*=2; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale2x1_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale2x2_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale2x3_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale2x4_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} + +void scale2x_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + swl *= 2; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < sw; x++, dx += 2) { pix = s[x]; - d[dx] = pix; d[dx+1] = pix; + d[dx] = pix; + d[dx + 1] = pix; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale2x1_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale2x2_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale2x3_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale2x4_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); } - -void scale3x_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, dpix1, dpix2, swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } swl*=3; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x<(sw/2); x++, dx+=3) { + void *__restrict dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale2x1_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale2x2_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale2x3_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale2x4_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale2x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} + +void scale3x_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, dpix1, dpix2, swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + swl *= 3; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < (sw / 2); x++, dx += 3) { pix = s[x]; - dpix1=(pix & 0x0000FFFF)|(pix<<16); - dpix2=(pix & 0xFFFF0000)|(pix>>16); - d[dx] = dpix1; d[dx+1] = pix; d[dx+2] = dpix2; + dpix1 = (pix & 0x0000FFFF) | (pix << 16); + dpix2 = (pix & 0xFFFF0000) | (pix >> 16); + d[dx] = dpix1; + d[dx + 1] = pix; + d[dx + 2] = dpix2; } - if (sw&1) { - uint16_t *s16 = (uint16_t*)s; - uint16_t *d16 = (uint16_t*)d; - uint16_t pix16 = s16[x*2]; - dpix1 = pix16|(pix16<<16); - d[dx] = dpix1; d16[(dx+1)*2] = pix16; + if (sw & 1) { + uint16_t *s16 = (uint16_t *)s; + uint16_t *d16 = (uint16_t *)d; + uint16_t pix16 = s16[x * 2]; + dpix1 = pix16 | (pix16 << 16); + d[dx] = dpix1; + d16[(dx + 1) * 2] = pix16; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale3x1_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale3x2_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale3x3_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale3x4_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); } - -void scale3x_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } swl*=3; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale3x1_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale3x2_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale3x3_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale3x4_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} + +void scale3x_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + swl *= 3; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < sw; x++, dx += 3) { pix = s[x]; - d[dx] = pix; d[dx+1] = pix; d[dx+2] = pix; + d[dx] = pix; + d[dx + 1] = pix; + d[dx + 2] = pix; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale3x1_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale3x2_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale3x3_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale3x4_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); } - -void scale4x_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, dpix1, dpix2, swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } swl*=4; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x<(sw/2); x++, dx+=4) { + void *__restrict dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale3x1_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale3x2_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale3x3_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale3x4_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale3x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} + +void scale4x_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, dpix1, dpix2, swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + swl *= 4; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < (sw / 2); x++, dx += 4) { pix = s[x]; - dpix1=(pix & 0x0000FFFF)|(pix<<16); - dpix2=(pix & 0xFFFF0000)|(pix>>16); - d[dx] = dpix1; d[dx+1] = dpix1; d[dx+2] = dpix2; d[dx+3] = dpix2; + dpix1 = (pix & 0x0000FFFF) | (pix << 16); + dpix2 = (pix & 0xFFFF0000) | (pix >> 16); + d[dx] = dpix1; + d[dx + 1] = dpix1; + d[dx + 2] = dpix2; + d[dx + 3] = dpix2; } - if (sw&1) { - uint16_t *s16 = (uint16_t*)s; - uint16_t pix16 = s16[x*2]; - dpix1 = pix16|(pix16<<16); - d[dx] = dpix1; d[dx+1] = dpix1; + if (sw & 1) { + uint16_t *s16 = (uint16_t *)s; + uint16_t pix16 = s16[x * 2]; + dpix1 = pix16 | (pix16 << 16); + d[dx] = dpix1; + d[dx + 1] = dpix1; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale4x1_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale4x2_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale4x3_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale4x4_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); } - -void scale4x_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } swl*=4; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale4x1_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale4x2_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale4x3_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale4x4_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} + +void scale4x_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + swl *= 4; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < sw; x++, dx += 4) { pix = s[x]; - d[dx] = pix; d[dx+1] = pix; d[dx+2] = pix; d[dx+3] = pix; + d[dx] = pix; + d[dx + 1] = pix; + d[dx + 2] = pix; + d[dx + 3] = pix; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale4x1_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale4x2_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale4x3_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale4x4_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); } - -void scale5x_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, dpix1, dpix2, swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } swl*=5; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x<(sw/2); x++, dx+=5) { + void *__restrict dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale4x1_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale4x2_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale4x3_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale4x4_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale4x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} + +void scale5x_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, dpix1, dpix2, swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + swl *= 5; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < (sw / 2); x++, dx += 5) { pix = s[x]; - dpix1=(pix & 0x0000FFFF)|(pix<<16); - dpix2=(pix & 0xFFFF0000)|(pix>>16); - d[dx] = dpix1; d[dx+1] = dpix1; d[dx+2] = pix; d[dx+3] = dpix2; d[dx+4] = dpix2; + dpix1 = (pix & 0x0000FFFF) | (pix << 16); + dpix2 = (pix & 0xFFFF0000) | (pix >> 16); + d[dx] = dpix1; + d[dx + 1] = dpix1; + d[dx + 2] = pix; + d[dx + 3] = dpix2; + d[dx + 4] = dpix2; } - if (sw&1) { - uint16_t *s16 = (uint16_t*)s; - uint16_t *d16 = (uint16_t*)d; - uint16_t pix16 = s16[x*2]; - dpix1 = pix16|(pix16<<16); - d[dx] = dpix1; d[dx+1] = dpix1; d16[(dx+2)*2] = pix16; + if (sw & 1) { + uint16_t *s16 = (uint16_t *)s; + uint16_t *d16 = (uint16_t *)d; + uint16_t pix16 = s16[x * 2]; + dpix1 = pix16 | (pix16 << 16); + d[dx] = dpix1; + d[dx + 1] = dpix1; + d16[(dx + 2) * 2] = pix16; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale5x1_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale5x2_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale5x3_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale5x4_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale5x5_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 5); } - -void scale5x_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } swl*=5; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale5x1_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale5x2_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale5x3_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale5x4_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale5x5_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, 5); +} + +void scale5x_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + swl *= 5; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < sw; x++, dx += 5) { pix = s[x]; - d[dx] = pix; d[dx+1] = pix; d[dx+2] = pix; d[dx+3] = pix; d[dx+4] = pix; + d[dx] = pix; + d[dx + 1] = pix; + d[dx + 2] = pix; + d[dx + 3] = pix; + d[dx + 4] = pix; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale5x1_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale5x2_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale5x3_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale5x4_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale5x5_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 5); } - -void scale6x_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, dpix1, dpix2, swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } swl*=6; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x<(sw/2); x++, dx+=6) { + void *__restrict dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale5x1_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale5x2_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale5x3_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale5x4_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale5x5_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, 5); +} + +void scale6x_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, dpix1, dpix2, swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + swl *= 6; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < (sw / 2); x++, dx += 6) { pix = s[x]; - dpix1=(pix & 0x0000FFFF)|(pix<<16); - dpix2=(pix & 0xFFFF0000)|(pix>>16); - d[dx] = dpix1; d[dx+1] = dpix1; d[dx+2] = dpix1; d[dx+3] = dpix2; d[dx+4] = dpix2; d[dx+5] = dpix2; + dpix1 = (pix & 0x0000FFFF) | (pix << 16); + dpix2 = (pix & 0xFFFF0000) | (pix >> 16); + d[dx] = dpix1; + d[dx + 1] = dpix1; + d[dx + 2] = dpix1; + d[dx + 3] = dpix2; + d[dx + 4] = dpix2; + d[dx + 5] = dpix2; } - if (sw&1) { - uint16_t *s16 = (uint16_t*)s; - uint16_t pix16 = s16[x*2]; - dpix1 = pix16|(pix16<<16); - d[dx] = dpix1; d[dx+1] = dpix1; d[dx+2] = dpix1; + if (sw & 1) { + uint16_t *s16 = (uint16_t *)s; + uint16_t pix16 = s16[x * 2]; + dpix1 = pix16 | (pix16 << 16); + d[dx] = dpix1; + d[dx + 1] = dpix1; + d[dx + 2] = dpix1; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); - } -} - -void scale6x1_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale6x2_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale6x3_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale6x4_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale6x5_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 5); } -void scale6x6_c16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 6); } - -void scale6x_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; - uint32_t x, dx, pix, swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } swl*=6; if (!dp) { dp = swl; } - for (; sh>0; sh--, src=(uint8_t*)src+sp) { - uint32_t *s = (uint32_t* __restrict)src; - uint32_t *d = (uint32_t* __restrict)dst; - for (x=dx=0; x 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); + } +} + +void scale6x1_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale6x2_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale6x3_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale6x4_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale6x5_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 5); +} +void scale6x6_c16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, 6); +} + +void scale6x_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; + uint32_t x, dx, pix, swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + swl *= 6; + if (!dp) { + dp = swl; + } + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { + uint32_t *s = (uint32_t *__restrict)src; + uint32_t *d = (uint32_t *__restrict)dst; + for (x = dx = 0; x < sw; x++, dx += 6) { pix = s[x]; - d[dx] = pix; d[dx+1] = pix; d[dx+2] = pix; d[dx+3] = pix; d[dx+4] = pix; d[dx+5] = pix; + d[dx] = pix; + d[dx + 1] = pix; + d[dx + 2] = pix; + d[dx + 3] = pix; + d[dx + 4] = pix; + d[dx + 5] = pix; } - void* __restrict dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy(dst, dstsrc, swl); + void *__restrict dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy(dst, dstsrc, swl); } } -void scale6x1_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale6x2_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale6x3_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale6x4_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale6x5_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 5); } -void scale6x6_c32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 6); } +void scale6x1_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale6x2_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale6x3_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale6x4_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale6x5_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 5); +} +void scale6x6_c32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, 6); +} #ifdef HAS_NEON // // memcpy_neon (dst/src must be aligned 4, size must be aligned 2) // -void memcpy_neon(void* dst, void* src, uint32_t size) { - asm volatile ( - " bic r4, %[sz], #127 ;" - " add r3, %[s], %[sz] ;" // r3 = endofs - " add r4, %[s], r4 ;" // r4 = s128ofs - " cmp %[s], r4 ;" - " beq 2f ;" - "1: vldmia %[s]!, {q8-q15} ;" // 128 bytes - " vstmia %[d]!, {q8-q15} ;" - " cmp %[s], r4 ;" - " bne 1b ;" - "2: cmp %[s], r3 ;" - " beq 7f ;" - " tst %[sz], #64 ;" - " beq 3f ;" - " vldmia %[s]!, {q8-q11} ;" // 64 bytes - " vstmia %[d]!, {q8-q11} ;" - " cmp %[s], r3 ;" - " beq 7f ;" - "3: tst %[sz], #32 ;" - " beq 4f ;" - " vldmia %[s]!, {q12-q13} ;" // 32 bytes - " vstmia %[d]!, {q12-q13} ;" - " cmp %[s], r3 ;" - " beq 7f ;" - "4: tst %[sz], #16 ;" - " beq 5f ;" - " vldmia %[s]!, {q14} ;" // 16 bytes - " vstmia %[d]!, {q14} ;" - " cmp %[s], r3 ;" - " beq 7f ;" - "5: tst %[sz], #8 ;" - " beq 6f ;" - " vldmia %[s]!, {d30} ;" // 8 bytes - " vstmia %[d]!, {d30} ;" - " cmp %[s], r3 ;" - " beq 7f ;" - "6: ldrh r4, [%[s]],#2 ;" // rest - " strh r4, [%[d]],#2 ;" - " cmp %[s], r3 ;" - " bne 6b ;" - "7: " - : [s]"+r"(src), [d]"+r"(dst) - : [sz]"r"(size) - : "r3","r4","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); +void memcpy_neon(void *dst, void *src, uint32_t size) +{ + asm volatile(" bic r4, %[sz], #127 ;" + " add r3, %[s], %[sz] ;" // r3 = endofs + " add r4, %[s], r4 ;" // r4 = s128ofs + " cmp %[s], r4 ;" + " beq 2f ;" + "1: vldmia %[s]!, {q8-q15} ;" // 128 bytes + " vstmia %[d]!, {q8-q15} ;" + " cmp %[s], r4 ;" + " bne 1b ;" + "2: cmp %[s], r3 ;" + " beq 7f ;" + " tst %[sz], #64 ;" + " beq 3f ;" + " vldmia %[s]!, {q8-q11} ;" // 64 bytes + " vstmia %[d]!, {q8-q11} ;" + " cmp %[s], r3 ;" + " beq 7f ;" + "3: tst %[sz], #32 ;" + " beq 4f ;" + " vldmia %[s]!, {q12-q13} ;" // 32 bytes + " vstmia %[d]!, {q12-q13} ;" + " cmp %[s], r3 ;" + " beq 7f ;" + "4: tst %[sz], #16 ;" + " beq 5f ;" + " vldmia %[s]!, {q14} ;" // 16 bytes + " vstmia %[d]!, {q14} ;" + " cmp %[s], r3 ;" + " beq 7f ;" + "5: tst %[sz], #8 ;" + " beq 6f ;" + " vldmia %[s]!, {d30} ;" // 8 bytes + " vstmia %[d]!, {d30} ;" + " cmp %[s], r3 ;" + " beq 7f ;" + "6: ldrh r4, [%[s]],#2 ;" // rest + " strh r4, [%[d]],#2 ;" + " cmp %[s], r3 ;" + " bne 6b ;" + "7: " + : [s] "+r"(src), [d] "+r"(dst) + : [sz] "r"(size) + : "r3", "r4", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); } // // NEON scalers // -void scale1x1_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*1; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x1_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } - if ((swl == sp)&&(sp == dp)) memcpy_neon(dst, src, sp*sh); +void scale1x1_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 1; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x1_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } + if ((swl == sp) && (sp == dp)) + memcpy_neon(dst, src, sp * sh); else { - if (swl>dp) swl = dp; - for (; sh>0; sh--, src=(uint8_t*)src+sp, dst=(uint8_t*)dst+dp) memcpy_neon(dst, src, swl); + if (swl > dp) + swl = dp; + for (; sh > 0; sh--, src = (uint8_t *)src + sp, dst = (uint8_t *)dst + dp) + memcpy_neon(dst, src, swl); } } -void scale1x2_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x2_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } +void scale1x2_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x2_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl128 = swl & ~127; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x128bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q15} ;" // 128 bytes - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " cmp %0, lr ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 8f ;" - " tst %3, #64 ;" - " beq 4f ;" - " vldmia %0!, {q8-q11} ;" // 64 bytes - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "4: tst %3, #32 ;" - " beq 5f ;" - " vldmia %0!, {q12-q13} ;" // 32 bytes - " vstmia %1!, {q12-q13} ;" - " vstmia r9!, {q12-q13} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "5: tst %3, #16 ;" - " beq 6f ;" - " vldmia %0!, {q14} ;" // 16 bytes - " vstmia %1!, {q14} ;" - " vstmia r9!, {q14} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "6: tst %3, #8 ;" - " beq 7f ;" - " vldmia %0!, {d30} ;" // 8 bytes - " vstmia %1!, {d30} ;" - " vstmia r9!, {d30} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "7: ldr lr, [%0],#4 ;" // 4 bytes - " str lr, [%1],#4 ;" - " str lr, [r9] ;" - "8: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale1x3_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x3_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + uint32_t dadd = dp * 2 - swl; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x128bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q15} ;" // 128 bytes + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " cmp %0, lr ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 8f ;" + " tst %3, #64 ;" + " beq 4f ;" + " vldmia %0!, {q8-q11} ;" // 64 bytes + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "4: tst %3, #32 ;" + " beq 5f ;" + " vldmia %0!, {q12-q13} ;" // 32 bytes + " vstmia %1!, {q12-q13} ;" + " vstmia r9!, {q12-q13} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "5: tst %3, #16 ;" + " beq 6f ;" + " vldmia %0!, {q14} ;" // 16 bytes + " vstmia %1!, {q14} ;" + " vstmia r9!, {q14} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "6: tst %3, #8 ;" + " beq 7f ;" + " vldmia %0!, {d30} ;" // 8 bytes + " vstmia %1!, {d30} ;" + " vstmia r9!, {d30} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "7: ldr lr, [%0],#4 ;" // 4 bytes + " str lr, [%1],#4 ;" + " str lr, [r9] ;" + "8: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale1x3_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x3_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl128 = swl & ~127; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x128bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q15} ;" // 128 bytes - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " cmp %0, lr ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 8f ;" - " tst %3, #64 ;" - " beq 4f ;" - " vldmia %0!, {q8-q11} ;" // 64 bytes - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " vstmia r10!, {q8-q11} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "4: tst %3, #32 ;" - " beq 5f ;" - " vldmia %0!, {q12-q13} ;" // 32 bytes - " vstmia %1!, {q12-q13} ;" - " vstmia r9!, {q12-q13} ;" - " vstmia r10!, {q12-q13} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "5: tst %3, #16 ;" - " beq 6f ;" - " vldmia %0!, {q14} ;" // 16 bytes - " vstmia %1!, {q14} ;" - " vstmia r9!, {q14} ;" - " vstmia r10!, {q14} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "6: tst %3, #8 ;" - " beq 7f ;" - " vldmia %0!, {d30} ;" // 8 bytes - " vstmia %1!, {d30} ;" - " vstmia r9!, {d30} ;" - " vstmia r10!, {d30} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "7: ldr lr, [%0],#4 ;" // 4 bytes - " str lr, [%1],#4 ;" - " str lr, [r9] ;" - " str lr, [r10] ;" - "8: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale1x4_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x4_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + uint32_t dadd = dp * 3 - swl; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x128bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q15} ;" // 128 bytes + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " cmp %0, lr ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 8f ;" + " tst %3, #64 ;" + " beq 4f ;" + " vldmia %0!, {q8-q11} ;" // 64 bytes + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " vstmia r10!, {q8-q11} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "4: tst %3, #32 ;" + " beq 5f ;" + " vldmia %0!, {q12-q13} ;" // 32 bytes + " vstmia %1!, {q12-q13} ;" + " vstmia r9!, {q12-q13} ;" + " vstmia r10!, {q12-q13} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "5: tst %3, #16 ;" + " beq 6f ;" + " vldmia %0!, {q14} ;" // 16 bytes + " vstmia %1!, {q14} ;" + " vstmia r9!, {q14} ;" + " vstmia r10!, {q14} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "6: tst %3, #8 ;" + " beq 7f ;" + " vldmia %0!, {d30} ;" // 8 bytes + " vstmia %1!, {d30} ;" + " vstmia r9!, {d30} ;" + " vstmia r10!, {d30} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "7: ldr lr, [%0],#4 ;" // 4 bytes + " str lr, [%1],#4 ;" + " str lr, [r9] ;" + " str lr, [r10] ;" + "8: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale1x4_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint16_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x4_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl128 = swl & ~127; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x128bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q15} ;" // 128 bytes - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " vstmia r11!, {q8-q15} ;" - " cmp %0, lr ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 8f ;" - " tst %3, #64 ;" - " beq 4f ;" - " vldmia %0!, {q8-q11} ;" // 64 bytes - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " vstmia r10!, {q8-q11} ;" - " vstmia r11!, {q8-q11} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "4: tst %3, #32 ;" - " beq 5f ;" - " vldmia %0!, {q12-q13} ;" // 32 bytes - " vstmia %1!, {q12-q13} ;" - " vstmia r9!, {q12-q13} ;" - " vstmia r10!, {q12-q13} ;" - " vstmia r11!, {q12-q13} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "5: tst %3, #16 ;" - " beq 6f ;" - " vldmia %0!, {q14} ;" // 16 bytes - " vstmia %1!, {q14} ;" - " vstmia r9!, {q14} ;" - " vstmia r10!, {q14} ;" - " vstmia r11!, {q14} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "6: tst %3, #8 ;" - " beq 7f ;" - " vldmia %0!, {d30} ;" // 8 bytes - " vstmia %1!, {d30} ;" - " vstmia r9!, {d30} ;" - " vstmia r10!, {d30} ;" - " vstmia r11!, {d30} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "7: ldr lr, [%0],#4 ;" // 4 bytes - " str lr, [%1],#4 ;" - " str lr, [r9] ;" - " str lr, [r10] ;" - " str lr, [r11] ;" - "8: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale1x_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale1x1_n16, &scale1x2_n16, &scale1x3_n16, &scale1x4_n16 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x128bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q15} ;" // 128 bytes + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " vstmia r11!, {q8-q15} ;" + " cmp %0, lr ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 8f ;" + " tst %3, #64 ;" + " beq 4f ;" + " vldmia %0!, {q8-q11} ;" // 64 bytes + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " vstmia r10!, {q8-q11} ;" + " vstmia r11!, {q8-q11} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "4: tst %3, #32 ;" + " beq 5f ;" + " vldmia %0!, {q12-q13} ;" // 32 bytes + " vstmia %1!, {q12-q13} ;" + " vstmia r9!, {q12-q13} ;" + " vstmia r10!, {q12-q13} ;" + " vstmia r11!, {q12-q13} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "5: tst %3, #16 ;" + " beq 6f ;" + " vldmia %0!, {q14} ;" // 16 bytes + " vstmia %1!, {q14} ;" + " vstmia r9!, {q14} ;" + " vstmia r10!, {q14} ;" + " vstmia r11!, {q14} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "6: tst %3, #8 ;" + " beq 7f ;" + " vldmia %0!, {d30} ;" // 8 bytes + " vstmia %1!, {d30} ;" + " vstmia r9!, {d30} ;" + " vstmia r10!, {d30} ;" + " vstmia r11!, {d30} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "7: ldr lr, [%0],#4 ;" // 4 bytes + " str lr, [%1],#4 ;" + " str lr, [r9] ;" + " str lr, [r10] ;" + " str lr, [r11] ;" + "8: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale1x_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale1x1_n16, &scale1x2_n16, &scale1x3_n16, &scale1x4_n16}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale1x1_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*1; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x1_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } - if ((swl == sp)&&(sp == dp)) memcpy_neon(dst, src, sp*sh); - else for (; sh>0; sh--, src=(uint8_t*)src+sp, dst=(uint8_t*)dst+dp) memcpy_neon(dst, src, swl); -} - -void scale1x2_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x2_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } +void scale1x1_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 1; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x1_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } + if ((swl == sp) && (sp == dp)) + memcpy_neon(dst, src, sp * sh); + else + for (; sh > 0; sh--, src = (uint8_t *)src + sp, dst = (uint8_t *)dst + dp) + memcpy_neon(dst, src, swl); +} + +void scale1x2_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x2_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl128 = swl & ~127; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x128bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q15} ;" // 128 bytes - " vstmia %1!, {q8-q15} ;" - " cmp %0, lr ;" - " vstmia r9!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 8f ;" - " tst %3, #64 ;" - " beq 4f ;" - " vldmia %0!, {q8-q11} ;" // 64 bytes - " vstmia %1!, {q8-q11} ;" - " cmp %0, r8 ;" - " vstmia r9!, {q8-q11} ;" - " beq 8f ;" - "4: tst %3, #32 ;" - " beq 5f ;" - " vldmia %0!, {q12-q13} ;" // 32 bytes - " vstmia %1!, {q12-q13} ;" - " cmp %0, r8 ;" - " vstmia r9!, {q12-q13} ;" - " beq 8f ;" - "5: tst %3, #16 ;" - " beq 6f ;" - " vldmia %0!, {q14} ;" // 16 bytes - " vstmia %1!, {q14} ;" - " cmp %0, r8 ;" - " vstmia r9!, {q14} ;" - " beq 8f ;" - "6: tst %3, #8 ;" - " beq 7f ;" - " vldmia %0!, {d30} ;" // 8 bytes - " vstmia %1!, {d30} ;" - " cmp %0, r8 ;" - " vstmia r9!, {d30} ;" - " beq 8f ;" - "7: ldr lr, [%0],#4 ;" // 4 bytes - " str lr, [%1],#4 ;" - " str lr, [r9] ;" - "8: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale1x3_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x3_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + uint32_t dadd = dp * 2 - swl; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x128bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q15} ;" // 128 bytes + " vstmia %1!, {q8-q15} ;" + " cmp %0, lr ;" + " vstmia r9!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 8f ;" + " tst %3, #64 ;" + " beq 4f ;" + " vldmia %0!, {q8-q11} ;" // 64 bytes + " vstmia %1!, {q8-q11} ;" + " cmp %0, r8 ;" + " vstmia r9!, {q8-q11} ;" + " beq 8f ;" + "4: tst %3, #32 ;" + " beq 5f ;" + " vldmia %0!, {q12-q13} ;" // 32 bytes + " vstmia %1!, {q12-q13} ;" + " cmp %0, r8 ;" + " vstmia r9!, {q12-q13} ;" + " beq 8f ;" + "5: tst %3, #16 ;" + " beq 6f ;" + " vldmia %0!, {q14} ;" // 16 bytes + " vstmia %1!, {q14} ;" + " cmp %0, r8 ;" + " vstmia r9!, {q14} ;" + " beq 8f ;" + "6: tst %3, #8 ;" + " beq 7f ;" + " vldmia %0!, {d30} ;" // 8 bytes + " vstmia %1!, {d30} ;" + " cmp %0, r8 ;" + " vstmia r9!, {d30} ;" + " beq 8f ;" + "7: ldr lr, [%0],#4 ;" // 4 bytes + " str lr, [%1],#4 ;" + " str lr, [r9] ;" + "8: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale1x3_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x3_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl128 = swl & ~127; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x128bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q15} ;" // 128 bytes - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " cmp %0, lr ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 8f ;" - " tst %3, #64 ;" - " beq 4f ;" - " vldmia %0!, {q8-q11} ;" // 64 bytes - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " vstmia r10!, {q8-q11} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "4: tst %3, #32 ;" - " beq 5f ;" - " vldmia %0!, {q12-q13} ;" // 32 bytes - " vstmia %1!, {q12-q13} ;" - " vstmia r9!, {q12-q13} ;" - " vstmia r10!, {q12-q13} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "5: tst %3, #16 ;" - " beq 6f ;" - " vldmia %0!, {q14} ;" // 16 bytes - " vstmia %1!, {q14} ;" - " vstmia r9!, {q14} ;" - " vstmia r10!, {q14} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "6: tst %3, #8 ;" - " beq 7f ;" - " vldmia %0!, {d30} ;" // 8 bytes - " vstmia %1!, {d30} ;" - " vstmia r9!, {d30} ;" - " vstmia r10!, {d30} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "7: ldr lr, [%0],#4 ;" // 4 bytes - " str lr, [%1],#4 ;" - " str lr, [r9] ;" - " str lr, [r10] ;" - "8: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale1x4_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; - uint32_t swl = sw*sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale1x4_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + uint32_t dadd = dp * 3 - swl; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x128bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q15} ;" // 128 bytes + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " cmp %0, lr ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 8f ;" + " tst %3, #64 ;" + " beq 4f ;" + " vldmia %0!, {q8-q11} ;" // 64 bytes + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " vstmia r10!, {q8-q11} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "4: tst %3, #32 ;" + " beq 5f ;" + " vldmia %0!, {q12-q13} ;" // 32 bytes + " vstmia %1!, {q12-q13} ;" + " vstmia r9!, {q12-q13} ;" + " vstmia r10!, {q12-q13} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "5: tst %3, #16 ;" + " beq 6f ;" + " vldmia %0!, {q14} ;" // 16 bytes + " vstmia %1!, {q14} ;" + " vstmia r9!, {q14} ;" + " vstmia r10!, {q14} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "6: tst %3, #8 ;" + " beq 7f ;" + " vldmia %0!, {d30} ;" // 8 bytes + " vstmia %1!, {d30} ;" + " vstmia r9!, {d30} ;" + " vstmia r10!, {d30} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "7: ldr lr, [%0],#4 ;" // 4 bytes + " str lr, [%1],#4 ;" + " str lr, [r9] ;" + " str lr, [r10] ;" + "8: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale1x4_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; + uint32_t swl = sw * sizeof(uint32_t); + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale1x4_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl128 = swl & ~127; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x128bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q15} ;" // 128 bytes - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " vstmia r11!, {q8-q15} ;" - " cmp %0, lr ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 8f ;" - " tst %3, #64 ;" - " beq 4f ;" - " vldmia %0!, {q8-q11} ;" // 64 bytes - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " vstmia r10!, {q8-q11} ;" - " vstmia r11!, {q8-q11} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "4: tst %3, #32 ;" - " beq 5f ;" - " vldmia %0!, {q12-q13} ;" // 32 bytes - " vstmia %1!, {q12-q13} ;" - " vstmia r9!, {q12-q13} ;" - " vstmia r10!, {q12-q13} ;" - " vstmia r11!, {q12-q13} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "5: tst %3, #16 ;" - " beq 6f ;" - " vldmia %0!, {q14} ;" // 16 bytes - " vstmia %1!, {q14} ;" - " vstmia r9!, {q14} ;" - " vstmia r10!, {q14} ;" - " vstmia r11!, {q14} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "6: tst %3, #8 ;" - " beq 7f ;" - " vldmia %0!, {d30} ;" // 8 bytes - " vstmia %1!, {d30} ;" - " vstmia r9!, {d30} ;" - " vstmia r10!, {d30} ;" - " vstmia r11!, {d30} ;" - " cmp %0, r8 ;" - " beq 8f ;" - "7: ldr lr, [%0],#4 ;" // 4 bytes - " str lr, [%1],#4 ;" - " str lr, [r9] ;" - " str lr, [r10] ;" - " str lr, [r11] ;" - "8: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale1x_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale1x1_n32, &scale1x2_n32, &scale1x3_n32, &scale1x4_n32 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x128bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q15} ;" // 128 bytes + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " vstmia r11!, {q8-q15} ;" + " cmp %0, lr ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 8f ;" + " tst %3, #64 ;" + " beq 4f ;" + " vldmia %0!, {q8-q11} ;" // 64 bytes + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " vstmia r10!, {q8-q11} ;" + " vstmia r11!, {q8-q11} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "4: tst %3, #32 ;" + " beq 5f ;" + " vldmia %0!, {q12-q13} ;" // 32 bytes + " vstmia %1!, {q12-q13} ;" + " vstmia r9!, {q12-q13} ;" + " vstmia r10!, {q12-q13} ;" + " vstmia r11!, {q12-q13} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "5: tst %3, #16 ;" + " beq 6f ;" + " vldmia %0!, {q14} ;" // 16 bytes + " vstmia %1!, {q14} ;" + " vstmia r9!, {q14} ;" + " vstmia r10!, {q14} ;" + " vstmia r11!, {q14} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "6: tst %3, #8 ;" + " beq 7f ;" + " vldmia %0!, {d30} ;" // 8 bytes + " vstmia %1!, {d30} ;" + " vstmia r9!, {d30} ;" + " vstmia r10!, {d30} ;" + " vstmia r11!, {d30} ;" + " cmp %0, r8 ;" + " beq 8f ;" + "7: ldr lr, [%0],#4 ;" // 4 bytes + " str lr, [%1],#4 ;" + " str lr, [r9] ;" + " str lr, [r10] ;" + " str lr, [r11] ;" + "8: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl128), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale1x_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale1x1_n32, &scale1x2_n32, &scale1x3_n32, &scale1x4_n32}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale2x1_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; +void scale2x1_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x1_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x1_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes - " vdup.16 d0, d23[3] ;" - " vdup.16 d1, d23[2] ;" - " vext.16 d31, d1,d0,#2 ;" - " vdup.16 d0, d23[1] ;" - " vdup.16 d1, d23[0] ;" - " vext.16 d30, d1,d0,#2 ;" - " vdup.16 d0, d22[3] ;" - " vdup.16 d1, d22[2] ;" - " vext.16 d29, d1,d0,#2 ;" - " vdup.16 d0, d22[1] ;" - " vdup.16 d1, d22[0] ;" - " vext.16 d28, d1,d0,#2 ;" - " vdup.16 d0, d21[3] ;" - " vdup.16 d1, d21[2] ;" - " vext.16 d27, d1,d0,#2 ;" - " vdup.16 d0, d21[1] ;" - " vdup.16 d1, d21[0] ;" - " vext.16 d26, d1,d0,#2 ;" - " vdup.16 d0, d20[3] ;" - " vdup.16 d1, d20[2] ;" - " vext.16 d25, d1,d0,#2 ;" - " vdup.16 d0, d20[1] ;" - " vdup.16 d1, d20[0] ;" - " vext.16 d24, d1,d0,#2 ;" - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - " tst %3, #32 ;" - " beq 4f ;" - " vldmia %0!,{q8-q9} ;" // 16 pixels - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8-q11} ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","lr","q0","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x2_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes + " vdup.16 d0, d23[3] ;" + " vdup.16 d1, d23[2] ;" + " vext.16 d31, d1,d0,#2 ;" + " vdup.16 d0, d23[1] ;" + " vdup.16 d1, d23[0] ;" + " vext.16 d30, d1,d0,#2 ;" + " vdup.16 d0, d22[3] ;" + " vdup.16 d1, d22[2] ;" + " vext.16 d29, d1,d0,#2 ;" + " vdup.16 d0, d22[1] ;" + " vdup.16 d1, d22[0] ;" + " vext.16 d28, d1,d0,#2 ;" + " vdup.16 d0, d21[3] ;" + " vdup.16 d1, d21[2] ;" + " vext.16 d27, d1,d0,#2 ;" + " vdup.16 d0, d21[1] ;" + " vdup.16 d1, d21[0] ;" + " vext.16 d26, d1,d0,#2 ;" + " vdup.16 d0, d20[3] ;" + " vdup.16 d1, d20[2] ;" + " vext.16 d25, d1,d0,#2 ;" + " vdup.16 d0, d20[1] ;" + " vdup.16 d1, d20[0] ;" + " vext.16 d24, d1,d0,#2 ;" + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + " tst %3, #32 ;" + " beq 4f ;" + " vldmia %0!,{q8-q9} ;" // 16 pixels + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8-q11} ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "lr", "q0", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale2x2_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x2_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x2_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes - " vdup.16 d0, d23[3] ;" - " vdup.16 d1, d23[2] ;" - " vext.16 d31, d1,d0,#2 ;" - " vdup.16 d0, d23[1] ;" - " vdup.16 d1, d23[0] ;" - " vext.16 d30, d1,d0,#2 ;" - " vdup.16 d0, d22[3] ;" - " vdup.16 d1, d22[2] ;" - " vext.16 d29, d1,d0,#2 ;" - " vdup.16 d0, d22[1] ;" - " vdup.16 d1, d22[0] ;" - " vext.16 d28, d1,d0,#2 ;" - " vdup.16 d0, d21[3] ;" - " vdup.16 d1, d21[2] ;" - " vext.16 d27, d1,d0,#2 ;" - " vdup.16 d0, d21[1] ;" - " vdup.16 d1, d21[0] ;" - " vext.16 d26, d1,d0,#2 ;" - " vdup.16 d0, d20[3] ;" - " vdup.16 d1, d20[2] ;" - " vext.16 d25, d1,d0,#2 ;" - " vdup.16 d0, d20[1] ;" - " vdup.16 d1, d20[0] ;" - " vext.16 d24, d1,d0,#2 ;" - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - " tst %3, #32 ;" - " beq 4f ;" - " vldmia %0!,{q8-q9} ;" // 16 pixels - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " str lr, [r9],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q0","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x3_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 2 - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes + " vdup.16 d0, d23[3] ;" + " vdup.16 d1, d23[2] ;" + " vext.16 d31, d1,d0,#2 ;" + " vdup.16 d0, d23[1] ;" + " vdup.16 d1, d23[0] ;" + " vext.16 d30, d1,d0,#2 ;" + " vdup.16 d0, d22[3] ;" + " vdup.16 d1, d22[2] ;" + " vext.16 d29, d1,d0,#2 ;" + " vdup.16 d0, d22[1] ;" + " vdup.16 d1, d22[0] ;" + " vext.16 d28, d1,d0,#2 ;" + " vdup.16 d0, d21[3] ;" + " vdup.16 d1, d21[2] ;" + " vext.16 d27, d1,d0,#2 ;" + " vdup.16 d0, d21[1] ;" + " vdup.16 d1, d21[0] ;" + " vext.16 d26, d1,d0,#2 ;" + " vdup.16 d0, d20[3] ;" + " vdup.16 d1, d20[2] ;" + " vext.16 d25, d1,d0,#2 ;" + " vdup.16 d0, d20[1] ;" + " vdup.16 d1, d20[0] ;" + " vext.16 d24, d1,d0,#2 ;" + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + " tst %3, #32 ;" + " beq 4f ;" + " vldmia %0!,{q8-q9} ;" // 16 pixels + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " str lr, [r9],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q0", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale2x3_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x3_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x3_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes - " vdup.16 d0, d23[3] ;" - " vdup.16 d1, d23[2] ;" - " vext.16 d31, d1,d0,#2 ;" - " vdup.16 d0, d23[1] ;" - " vdup.16 d1, d23[0] ;" - " vext.16 d30, d1,d0,#2 ;" - " vdup.16 d0, d22[3] ;" - " vdup.16 d1, d22[2] ;" - " vext.16 d29, d1,d0,#2 ;" - " vdup.16 d0, d22[1] ;" - " vdup.16 d1, d22[0] ;" - " vext.16 d28, d1,d0,#2 ;" - " vdup.16 d0, d21[3] ;" - " vdup.16 d1, d21[2] ;" - " vext.16 d27, d1,d0,#2 ;" - " vdup.16 d0, d21[1] ;" - " vdup.16 d1, d21[0] ;" - " vext.16 d26, d1,d0,#2 ;" - " vdup.16 d0, d20[3] ;" - " vdup.16 d1, d20[2] ;" - " vext.16 d25, d1,d0,#2 ;" - " vdup.16 d0, d20[1] ;" - " vdup.16 d1, d20[0] ;" - " vext.16 d24, d1,d0,#2 ;" - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - " tst %3, #32 ;" - " beq 4f ;" - " vldmia %0!,{q8-q9} ;" // 16 pixels - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " vstmia r10!, {q8-q11} ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " str lr, [r9],#4 ;" - " str lr, [r10],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q0","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x4_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 3 - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes + " vdup.16 d0, d23[3] ;" + " vdup.16 d1, d23[2] ;" + " vext.16 d31, d1,d0,#2 ;" + " vdup.16 d0, d23[1] ;" + " vdup.16 d1, d23[0] ;" + " vext.16 d30, d1,d0,#2 ;" + " vdup.16 d0, d22[3] ;" + " vdup.16 d1, d22[2] ;" + " vext.16 d29, d1,d0,#2 ;" + " vdup.16 d0, d22[1] ;" + " vdup.16 d1, d22[0] ;" + " vext.16 d28, d1,d0,#2 ;" + " vdup.16 d0, d21[3] ;" + " vdup.16 d1, d21[2] ;" + " vext.16 d27, d1,d0,#2 ;" + " vdup.16 d0, d21[1] ;" + " vdup.16 d1, d21[0] ;" + " vext.16 d26, d1,d0,#2 ;" + " vdup.16 d0, d20[3] ;" + " vdup.16 d1, d20[2] ;" + " vext.16 d25, d1,d0,#2 ;" + " vdup.16 d0, d20[1] ;" + " vdup.16 d1, d20[0] ;" + " vext.16 d24, d1,d0,#2 ;" + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + " tst %3, #32 ;" + " beq 4f ;" + " vldmia %0!,{q8-q9} ;" // 16 pixels + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " vstmia r10!, {q8-q11} ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " str lr, [r9],#4 ;" + " str lr, [r10],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q0", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale2x4_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x3_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x3_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes - " vdup.16 d0, d23[3] ;" - " vdup.16 d1, d23[2] ;" - " vext.16 d31, d1,d0,#2 ;" - " vdup.16 d0, d23[1] ;" - " vdup.16 d1, d23[0] ;" - " vext.16 d30, d1,d0,#2 ;" - " vdup.16 d0, d22[3] ;" - " vdup.16 d1, d22[2] ;" - " vext.16 d29, d1,d0,#2 ;" - " vdup.16 d0, d22[1] ;" - " vdup.16 d1, d22[0] ;" - " vext.16 d28, d1,d0,#2 ;" - " vdup.16 d0, d21[3] ;" - " vdup.16 d1, d21[2] ;" - " vext.16 d27, d1,d0,#2 ;" - " vdup.16 d0, d21[1] ;" - " vdup.16 d1, d21[0] ;" - " vext.16 d26, d1,d0,#2 ;" - " vdup.16 d0, d20[3] ;" - " vdup.16 d1, d20[2] ;" - " vext.16 d25, d1,d0,#2 ;" - " vdup.16 d0, d20[1] ;" - " vdup.16 d1, d20[0] ;" - " vext.16 d24, d1,d0,#2 ;" - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " vstmia r11!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - " tst %3, #32 ;" - " beq 4f ;" - " vldmia %0!,{q8-q9} ;" // 16 pixels - " vdup.16 d0, d19[3] ;" - " vdup.16 d1, d19[2] ;" - " vext.16 d23, d1,d0,#2 ;" - " vdup.16 d0, d19[1] ;" - " vdup.16 d1, d19[0] ;" - " vext.16 d22, d1,d0,#2 ;" - " vdup.16 d0, d18[3] ;" - " vdup.16 d1, d18[2] ;" - " vext.16 d21, d1,d0,#2 ;" - " vdup.16 d0, d18[1] ;" - " vdup.16 d1, d18[0] ;" - " vext.16 d20, d1,d0,#2 ;" - " vdup.16 d0, d17[3] ;" - " vdup.16 d1, d17[2] ;" - " vext.16 d19, d1,d0,#2 ;" - " vdup.16 d0, d17[1] ;" - " vdup.16 d1, d17[0] ;" - " vext.16 d18, d1,d0,#2 ;" - " vdup.16 d0, d16[3] ;" - " vdup.16 d1, d16[2] ;" - " vext.16 d17, d1,d0,#2 ;" - " vdup.16 d0, d16[1] ;" - " vdup.16 d1, d16[0] ;" - " vext.16 d16, d1,d0,#2 ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8-q11} ;" - " vstmia r9!, {q8-q11} ;" - " vstmia r10!, {q8-q11} ;" - " vstmia r11!, {q8-q11} ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " str lr, [r9],#4 ;" - " str lr, [r10],#4 ;" - " str lr, [r11],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q0","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale2x1_n16, &scale2x2_n16, &scale2x3_n16, &scale2x4_n16 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 32 pixels 64 bytes + " vdup.16 d0, d23[3] ;" + " vdup.16 d1, d23[2] ;" + " vext.16 d31, d1,d0,#2 ;" + " vdup.16 d0, d23[1] ;" + " vdup.16 d1, d23[0] ;" + " vext.16 d30, d1,d0,#2 ;" + " vdup.16 d0, d22[3] ;" + " vdup.16 d1, d22[2] ;" + " vext.16 d29, d1,d0,#2 ;" + " vdup.16 d0, d22[1] ;" + " vdup.16 d1, d22[0] ;" + " vext.16 d28, d1,d0,#2 ;" + " vdup.16 d0, d21[3] ;" + " vdup.16 d1, d21[2] ;" + " vext.16 d27, d1,d0,#2 ;" + " vdup.16 d0, d21[1] ;" + " vdup.16 d1, d21[0] ;" + " vext.16 d26, d1,d0,#2 ;" + " vdup.16 d0, d20[3] ;" + " vdup.16 d1, d20[2] ;" + " vext.16 d25, d1,d0,#2 ;" + " vdup.16 d0, d20[1] ;" + " vdup.16 d1, d20[0] ;" + " vext.16 d24, d1,d0,#2 ;" + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " vstmia r11!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + " tst %3, #32 ;" + " beq 4f ;" + " vldmia %0!,{q8-q9} ;" // 16 pixels + " vdup.16 d0, d19[3] ;" + " vdup.16 d1, d19[2] ;" + " vext.16 d23, d1,d0,#2 ;" + " vdup.16 d0, d19[1] ;" + " vdup.16 d1, d19[0] ;" + " vext.16 d22, d1,d0,#2 ;" + " vdup.16 d0, d18[3] ;" + " vdup.16 d1, d18[2] ;" + " vext.16 d21, d1,d0,#2 ;" + " vdup.16 d0, d18[1] ;" + " vdup.16 d1, d18[0] ;" + " vext.16 d20, d1,d0,#2 ;" + " vdup.16 d0, d17[3] ;" + " vdup.16 d1, d17[2] ;" + " vext.16 d19, d1,d0,#2 ;" + " vdup.16 d0, d17[1] ;" + " vdup.16 d1, d17[0] ;" + " vext.16 d18, d1,d0,#2 ;" + " vdup.16 d0, d16[3] ;" + " vdup.16 d1, d16[2] ;" + " vext.16 d17, d1,d0,#2 ;" + " vdup.16 d0, d16[1] ;" + " vdup.16 d1, d16[0] ;" + " vext.16 d16, d1,d0,#2 ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8-q11} ;" + " vstmia r9!, {q8-q11} ;" + " vstmia r10!, {q8-q11} ;" + " vstmia r11!, {q8-q11} ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " str lr, [r9],#4 ;" + " str lr, [r10],#4 ;" + " str lr, [r11],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q0", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale2x_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale2x1_n16, &scale2x2_n16, &scale2x3_n16, &scale2x4_n16}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale2x1_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; +void scale2x1_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x1_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x1_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes - " vdup.32 d31, d23[1] ;" - " vdup.32 d30, d23[0] ;" - " vdup.32 d29, d22[1] ;" - " vdup.32 d28, d22[0] ;" - " vdup.32 d27, d21[1] ;" - " vdup.32 d26, d21[0] ;" - " vdup.32 d25, d20[1] ;" - " vdup.32 d24, d20[0] ;" - " vdup.32 d23, d19[1] ;" - " vdup.32 d22, d19[0] ;" - " vdup.32 d21, d18[1] ;" - " vdup.32 d20, d18[0] ;" - " vdup.32 d19, d17[1] ;" - " vdup.32 d18, d17[0] ;" - " vdup.32 d17, d16[1] ;" - " vdup.32 d16, d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x2_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes + " vdup.32 d31, d23[1] ;" + " vdup.32 d30, d23[0] ;" + " vdup.32 d29, d22[1] ;" + " vdup.32 d28, d22[0] ;" + " vdup.32 d27, d21[1] ;" + " vdup.32 d26, d21[0] ;" + " vdup.32 d25, d20[1] ;" + " vdup.32 d24, d20[0] ;" + " vdup.32 d23, d19[1] ;" + " vdup.32 d22, d19[0] ;" + " vdup.32 d21, d18[1] ;" + " vdup.32 d20, d18[0] ;" + " vdup.32 d19, d17[1] ;" + " vdup.32 d18, d17[0] ;" + " vdup.32 d17, d16[1] ;" + " vdup.32 d16, d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale2x2_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x2_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x2_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes - " vdup.32 d31, d23[1] ;" - " vdup.32 d30, d23[0] ;" - " vdup.32 d29, d22[1] ;" - " vdup.32 d28, d22[0] ;" - " vdup.32 d27, d21[1] ;" - " vdup.32 d26, d21[0] ;" - " vdup.32 d25, d20[1] ;" - " vdup.32 d24, d20[0] ;" - " vdup.32 d23, d19[1] ;" - " vdup.32 d22, d19[0] ;" - " vdup.32 d21, d18[1] ;" - " vdup.32 d20, d18[0] ;" - " vdup.32 d19, d17[1] ;" - " vdup.32 d18, d17[0] ;" - " vdup.32 d17, d16[1] ;" - " vdup.32 d16, d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " vstmia r9!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x3_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 2 - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes + " vdup.32 d31, d23[1] ;" + " vdup.32 d30, d23[0] ;" + " vdup.32 d29, d22[1] ;" + " vdup.32 d28, d22[0] ;" + " vdup.32 d27, d21[1] ;" + " vdup.32 d26, d21[0] ;" + " vdup.32 d25, d20[1] ;" + " vdup.32 d24, d20[0] ;" + " vdup.32 d23, d19[1] ;" + " vdup.32 d22, d19[0] ;" + " vdup.32 d21, d18[1] ;" + " vdup.32 d20, d18[0] ;" + " vdup.32 d19, d17[1] ;" + " vdup.32 d18, d17[0] ;" + " vdup.32 d17, d16[1] ;" + " vdup.32 d16, d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " vstmia r9!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale2x3_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x3_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x3_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes - " vdup.32 d31, d23[1] ;" - " vdup.32 d30, d23[0] ;" - " vdup.32 d29, d22[1] ;" - " vdup.32 d28, d22[0] ;" - " vdup.32 d27, d21[1] ;" - " vdup.32 d26, d21[0] ;" - " vdup.32 d25, d20[1] ;" - " vdup.32 d24, d20[0] ;" - " vdup.32 d23, d19[1] ;" - " vdup.32 d22, d19[0] ;" - " vdup.32 d21, d18[1] ;" - " vdup.32 d20, d18[0] ;" - " vdup.32 d19, d17[1] ;" - " vdup.32 d18, d17[0] ;" - " vdup.32 d17, d16[1] ;" - " vdup.32 d16, d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " vstmia r9!, {d16} ;" - " vstmia r10!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x4_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 3 - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes + " vdup.32 d31, d23[1] ;" + " vdup.32 d30, d23[0] ;" + " vdup.32 d29, d22[1] ;" + " vdup.32 d28, d22[0] ;" + " vdup.32 d27, d21[1] ;" + " vdup.32 d26, d21[0] ;" + " vdup.32 d25, d20[1] ;" + " vdup.32 d24, d20[0] ;" + " vdup.32 d23, d19[1] ;" + " vdup.32 d22, d19[0] ;" + " vdup.32 d21, d18[1] ;" + " vdup.32 d20, d18[0] ;" + " vdup.32 d19, d17[1] ;" + " vdup.32 d18, d17[0] ;" + " vdup.32 d17, d16[1] ;" + " vdup.32 d16, d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " vstmia r9!, {d16} ;" + " vstmia r10!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale2x4_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*2; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale2x4_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 2; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale2x4_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl64 = swl & ~63; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl*2; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x64bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes - " vdup.32 d31, d23[1] ;" - " vdup.32 d30, d23[0] ;" - " vdup.32 d29, d22[1] ;" - " vdup.32 d28, d22[0] ;" - " vdup.32 d27, d21[1] ;" - " vdup.32 d26, d21[0] ;" - " vdup.32 d25, d20[1] ;" - " vdup.32 d24, d20[0] ;" - " vdup.32 d23, d19[1] ;" - " vdup.32 d22, d19[0] ;" - " vdup.32 d21, d18[1] ;" - " vdup.32 d20, d18[0] ;" - " vdup.32 d19, d17[1] ;" - " vdup.32 d18, d17[0] ;" - " vdup.32 d17, d16[1] ;" - " vdup.32 d16, d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!, {q8-q15} ;" - " vstmia r9!, {q8-q15} ;" - " vstmia r10!, {q8-q15} ;" - " vstmia r11!, {q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " vstmia r9!, {d16} ;" - " vstmia r10!, {d16} ;" - " vstmia r11!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale2x_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale2x1_n32, &scale2x2_n32, &scale2x3_n32, &scale2x4_n32 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl * 2; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x64bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q11} ;" // 16 pixels 64 bytes + " vdup.32 d31, d23[1] ;" + " vdup.32 d30, d23[0] ;" + " vdup.32 d29, d22[1] ;" + " vdup.32 d28, d22[0] ;" + " vdup.32 d27, d21[1] ;" + " vdup.32 d26, d21[0] ;" + " vdup.32 d25, d20[1] ;" + " vdup.32 d24, d20[0] ;" + " vdup.32 d23, d19[1] ;" + " vdup.32 d22, d19[0] ;" + " vdup.32 d21, d18[1] ;" + " vdup.32 d20, d18[0] ;" + " vdup.32 d19, d17[1] ;" + " vdup.32 d18, d17[0] ;" + " vdup.32 d17, d16[1] ;" + " vdup.32 d16, d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!, {q8-q15} ;" + " vstmia r9!, {q8-q15} ;" + " vstmia r10!, {q8-q15} ;" + " vstmia r11!, {q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " vstmia r9!, {d16} ;" + " vstmia r10!, {d16} ;" + " vstmia r11!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl64), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale2x_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale2x1_n32, &scale2x2_n32, &scale2x3_n32, &scale2x4_n32}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale3x1_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; +void scale3x1_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x1_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x1_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31, d19[3] ;" // FFFF - " vdup.16 d30, d19[2] ;" // EEEE - " vdup.16 d29, d19[1] ;" // DDDD - " vdup.16 d28, d19[0] ;" // CCCC - " vext.16 d27, d30,d31,#3 ;" // EFFF - " vext.16 d26, d29,d30,#2 ;" // DDEE - " vext.16 d25, d28,d29,#1 ;" // CCCD - " vdup.16 d31, d18[3] ;" // BBBB - " vdup.16 d30, d18[2] ;" // AAAA - " vdup.16 d29, d18[1] ;" // 9999 - " vdup.16 d28, d18[0] ;" // 8888 - " vext.16 d24, d30,d31,#3 ;" // ABBB - " vext.16 d23, d29,d30,#2 ;" // 99AA - " vext.16 d22, d28,d29,#1 ;" // 8889 - " vdup.16 d31, d17[3] ;" // 7777 - " vdup.16 d30, d17[2] ;" // 6666 - " vdup.16 d29, d17[1] ;" // 5555 - " vdup.16 d28, d17[0] ;" // 4444 - " vext.16 d21, d30,d31,#3 ;" // 6777 - " vext.16 d20, d29,d30,#2 ;" // 5566 - " vext.16 d19, d28,d29,#1 ;" // 4445 - " vdup.16 d31, d16[3] ;" // 3333 - " vdup.16 d30, d16[2] ;" // 2222 - " vdup.16 d29, d16[1] ;" // 1111 - " vdup.16 d28, d16[0] ;" // 0000 - " vext.16 d18, d30,d31,#3 ;" // 2333 - " vext.16 d17, d29,d30,#2 ;" // 1122 - " vext.16 d16, d28,d29,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!, {q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " strh lr, [%1],#2 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x2_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31, d19[3] ;" // FFFF + " vdup.16 d30, d19[2] ;" // EEEE + " vdup.16 d29, d19[1] ;" // DDDD + " vdup.16 d28, d19[0] ;" // CCCC + " vext.16 d27, d30,d31,#3 ;" // EFFF + " vext.16 d26, d29,d30,#2 ;" // DDEE + " vext.16 d25, d28,d29,#1 ;" // CCCD + " vdup.16 d31, d18[3] ;" // BBBB + " vdup.16 d30, d18[2] ;" // AAAA + " vdup.16 d29, d18[1] ;" // 9999 + " vdup.16 d28, d18[0] ;" // 8888 + " vext.16 d24, d30,d31,#3 ;" // ABBB + " vext.16 d23, d29,d30,#2 ;" // 99AA + " vext.16 d22, d28,d29,#1 ;" // 8889 + " vdup.16 d31, d17[3] ;" // 7777 + " vdup.16 d30, d17[2] ;" // 6666 + " vdup.16 d29, d17[1] ;" // 5555 + " vdup.16 d28, d17[0] ;" // 4444 + " vext.16 d21, d30,d31,#3 ;" // 6777 + " vext.16 d20, d29,d30,#2 ;" // 5566 + " vext.16 d19, d28,d29,#1 ;" // 4445 + " vdup.16 d31, d16[3] ;" // 3333 + " vdup.16 d30, d16[2] ;" // 2222 + " vdup.16 d29, d16[1] ;" // 1111 + " vdup.16 d28, d16[0] ;" // 0000 + " vext.16 d18, d30,d31,#3 ;" // 2333 + " vext.16 d17, d29,d30,#2 ;" // 1122 + " vext.16 d16, d28,d29,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!, {q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " strh lr, [%1],#2 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale3x2_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x2_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x2_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31, d19[3] ;" // FFFF - " vdup.16 d30, d19[2] ;" // EEEE - " vdup.16 d29, d19[1] ;" // DDDD - " vdup.16 d28, d19[0] ;" // CCCC - " vext.16 d27, d30,d31,#3 ;" // EFFF - " vext.16 d26, d29,d30,#2 ;" // DDEE - " vext.16 d25, d28,d29,#1 ;" // CCCD - " vdup.16 d31, d18[3] ;" // BBBB - " vdup.16 d30, d18[2] ;" // AAAA - " vdup.16 d29, d18[1] ;" // 9999 - " vdup.16 d28, d18[0] ;" // 8888 - " vext.16 d24, d30,d31,#3 ;" // ABBB - " vext.16 d23, d29,d30,#2 ;" // 99AA - " vext.16 d22, d28,d29,#1 ;" // 8889 - " vdup.16 d31, d17[3] ;" // 7777 - " vdup.16 d30, d17[2] ;" // 6666 - " vdup.16 d29, d17[1] ;" // 5555 - " vdup.16 d28, d17[0] ;" // 4444 - " vext.16 d21, d30,d31,#3 ;" // 6777 - " vext.16 d20, d29,d30,#2 ;" // 5566 - " vext.16 d19, d28,d29,#1 ;" // 4445 - " vdup.16 d31, d16[3] ;" // 3333 - " vdup.16 d30, d16[2] ;" // 2222 - " vdup.16 d29, d16[1] ;" // 1111 - " vdup.16 d28, d16[0] ;" // 0000 - " vext.16 d18, d30,d31,#3 ;" // 2333 - " vext.16 d17, d29,d30,#2 ;" // 1122 - " vext.16 d16, d28,d29,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!, {q8-q13} ;" - " vstmia r9!, {q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " strh lr, [%1],#2 ;" - " str lr, [r9],#4 ;" - " strh lr, [r9],#2 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x3_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 2 - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31, d19[3] ;" // FFFF + " vdup.16 d30, d19[2] ;" // EEEE + " vdup.16 d29, d19[1] ;" // DDDD + " vdup.16 d28, d19[0] ;" // CCCC + " vext.16 d27, d30,d31,#3 ;" // EFFF + " vext.16 d26, d29,d30,#2 ;" // DDEE + " vext.16 d25, d28,d29,#1 ;" // CCCD + " vdup.16 d31, d18[3] ;" // BBBB + " vdup.16 d30, d18[2] ;" // AAAA + " vdup.16 d29, d18[1] ;" // 9999 + " vdup.16 d28, d18[0] ;" // 8888 + " vext.16 d24, d30,d31,#3 ;" // ABBB + " vext.16 d23, d29,d30,#2 ;" // 99AA + " vext.16 d22, d28,d29,#1 ;" // 8889 + " vdup.16 d31, d17[3] ;" // 7777 + " vdup.16 d30, d17[2] ;" // 6666 + " vdup.16 d29, d17[1] ;" // 5555 + " vdup.16 d28, d17[0] ;" // 4444 + " vext.16 d21, d30,d31,#3 ;" // 6777 + " vext.16 d20, d29,d30,#2 ;" // 5566 + " vext.16 d19, d28,d29,#1 ;" // 4445 + " vdup.16 d31, d16[3] ;" // 3333 + " vdup.16 d30, d16[2] ;" // 2222 + " vdup.16 d29, d16[1] ;" // 1111 + " vdup.16 d28, d16[0] ;" // 0000 + " vext.16 d18, d30,d31,#3 ;" // 2333 + " vext.16 d17, d29,d30,#2 ;" // 1122 + " vext.16 d16, d28,d29,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!, {q8-q13} ;" + " vstmia r9!, {q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " strh lr, [%1],#2 ;" + " str lr, [r9],#4 ;" + " strh lr, [r9],#2 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale3x3_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x3_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x3_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31, d19[3] ;" // FFFF - " vdup.16 d30, d19[2] ;" // EEEE - " vdup.16 d29, d19[1] ;" // DDDD - " vdup.16 d28, d19[0] ;" // CCCC - " vext.16 d27, d30,d31,#3 ;" // EFFF - " vext.16 d26, d29,d30,#2 ;" // DDEE - " vext.16 d25, d28,d29,#1 ;" // CCCD - " vdup.16 d31, d18[3] ;" // BBBB - " vdup.16 d30, d18[2] ;" // AAAA - " vdup.16 d29, d18[1] ;" // 9999 - " vdup.16 d28, d18[0] ;" // 8888 - " vext.16 d24, d30,d31,#3 ;" // ABBB - " vext.16 d23, d29,d30,#2 ;" // 99AA - " vext.16 d22, d28,d29,#1 ;" // 8889 - " vdup.16 d31, d17[3] ;" // 7777 - " vdup.16 d30, d17[2] ;" // 6666 - " vdup.16 d29, d17[1] ;" // 5555 - " vdup.16 d28, d17[0] ;" // 4444 - " vext.16 d21, d30,d31,#3 ;" // 6777 - " vext.16 d20, d29,d30,#2 ;" // 5566 - " vext.16 d19, d28,d29,#1 ;" // 4445 - " vdup.16 d31, d16[3] ;" // 3333 - " vdup.16 d30, d16[2] ;" // 2222 - " vdup.16 d29, d16[1] ;" // 1111 - " vdup.16 d28, d16[0] ;" // 0000 - " vext.16 d18, d30,d31,#3 ;" // 2333 - " vext.16 d17, d29,d30,#2 ;" // 1122 - " vext.16 d16, d28,d29,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!, {q8-q13} ;" - " vstmia r9!, {q8-q13} ;" - " vstmia r10!, {q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " strh lr, [%1],#2 ;" - " str lr, [r9],#4 ;" - " strh lr, [r9],#2 ;" - " str lr, [r10],#4 ;" - " strh lr, [r10],#2 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x4_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 3 - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31, d19[3] ;" // FFFF + " vdup.16 d30, d19[2] ;" // EEEE + " vdup.16 d29, d19[1] ;" // DDDD + " vdup.16 d28, d19[0] ;" // CCCC + " vext.16 d27, d30,d31,#3 ;" // EFFF + " vext.16 d26, d29,d30,#2 ;" // DDEE + " vext.16 d25, d28,d29,#1 ;" // CCCD + " vdup.16 d31, d18[3] ;" // BBBB + " vdup.16 d30, d18[2] ;" // AAAA + " vdup.16 d29, d18[1] ;" // 9999 + " vdup.16 d28, d18[0] ;" // 8888 + " vext.16 d24, d30,d31,#3 ;" // ABBB + " vext.16 d23, d29,d30,#2 ;" // 99AA + " vext.16 d22, d28,d29,#1 ;" // 8889 + " vdup.16 d31, d17[3] ;" // 7777 + " vdup.16 d30, d17[2] ;" // 6666 + " vdup.16 d29, d17[1] ;" // 5555 + " vdup.16 d28, d17[0] ;" // 4444 + " vext.16 d21, d30,d31,#3 ;" // 6777 + " vext.16 d20, d29,d30,#2 ;" // 5566 + " vext.16 d19, d28,d29,#1 ;" // 4445 + " vdup.16 d31, d16[3] ;" // 3333 + " vdup.16 d30, d16[2] ;" // 2222 + " vdup.16 d29, d16[1] ;" // 1111 + " vdup.16 d28, d16[0] ;" // 0000 + " vext.16 d18, d30,d31,#3 ;" // 2333 + " vext.16 d17, d29,d30,#2 ;" // 1122 + " vext.16 d16, d28,d29,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!, {q8-q13} ;" + " vstmia r9!, {q8-q13} ;" + " vstmia r10!, {q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " strh lr, [%1],#2 ;" + " str lr, [r9],#4 ;" + " strh lr, [r9],#2 ;" + " str lr, [r10],#4 ;" + " strh lr, [r10],#2 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale3x4_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x4_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x4_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31, d19[3] ;" // FFFF - " vdup.16 d30, d19[2] ;" // EEEE - " vdup.16 d29, d19[1] ;" // DDDD - " vdup.16 d28, d19[0] ;" // CCCC - " vext.16 d27, d30,d31,#3 ;" // EFFF - " vext.16 d26, d29,d30,#2 ;" // DDEE - " vext.16 d25, d28,d29,#1 ;" // CCCD - " vdup.16 d31, d18[3] ;" // BBBB - " vdup.16 d30, d18[2] ;" // AAAA - " vdup.16 d29, d18[1] ;" // 9999 - " vdup.16 d28, d18[0] ;" // 8888 - " vext.16 d24, d30,d31,#3 ;" // ABBB - " vext.16 d23, d29,d30,#2 ;" // 99AA - " vext.16 d22, d28,d29,#1 ;" // 8889 - " vdup.16 d31, d17[3] ;" // 7777 - " vdup.16 d30, d17[2] ;" // 6666 - " vdup.16 d29, d17[1] ;" // 5555 - " vdup.16 d28, d17[0] ;" // 4444 - " vext.16 d21, d30,d31,#3 ;" // 6777 - " vext.16 d20, d29,d30,#2 ;" // 5566 - " vext.16 d19, d28,d29,#1 ;" // 4445 - " vdup.16 d31, d16[3] ;" // 3333 - " vdup.16 d30, d16[2] ;" // 2222 - " vdup.16 d29, d16[1] ;" // 1111 - " vdup.16 d28, d16[0] ;" // 0000 - " vext.16 d18, d30,d31,#3 ;" // 2333 - " vext.16 d17, d29,d30,#2 ;" // 1122 - " vext.16 d16, d28,d29,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!, {q8-q13} ;" - " vstmia r9!, {q8-q13} ;" - " vstmia r10!, {q8-q13} ;" - " vstmia r11!, {q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " orr lr, lr, lsl #16 ;" - " cmp %0, r8 ;" - " str lr, [%1],#4 ;" - " strh lr, [%1],#2 ;" - " str lr, [r9],#4 ;" - " strh lr, [r9],#2 ;" - " str lr, [r10],#4 ;" - " strh lr, [r10],#2 ;" - " str lr, [r11],#4 ;" - " strh lr, [r11],#2 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale3x1_n16, &scale3x2_n16, &scale3x3_n16, &scale3x4_n16 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!, {q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31, d19[3] ;" // FFFF + " vdup.16 d30, d19[2] ;" // EEEE + " vdup.16 d29, d19[1] ;" // DDDD + " vdup.16 d28, d19[0] ;" // CCCC + " vext.16 d27, d30,d31,#3 ;" // EFFF + " vext.16 d26, d29,d30,#2 ;" // DDEE + " vext.16 d25, d28,d29,#1 ;" // CCCD + " vdup.16 d31, d18[3] ;" // BBBB + " vdup.16 d30, d18[2] ;" // AAAA + " vdup.16 d29, d18[1] ;" // 9999 + " vdup.16 d28, d18[0] ;" // 8888 + " vext.16 d24, d30,d31,#3 ;" // ABBB + " vext.16 d23, d29,d30,#2 ;" // 99AA + " vext.16 d22, d28,d29,#1 ;" // 8889 + " vdup.16 d31, d17[3] ;" // 7777 + " vdup.16 d30, d17[2] ;" // 6666 + " vdup.16 d29, d17[1] ;" // 5555 + " vdup.16 d28, d17[0] ;" // 4444 + " vext.16 d21, d30,d31,#3 ;" // 6777 + " vext.16 d20, d29,d30,#2 ;" // 5566 + " vext.16 d19, d28,d29,#1 ;" // 4445 + " vdup.16 d31, d16[3] ;" // 3333 + " vdup.16 d30, d16[2] ;" // 2222 + " vdup.16 d29, d16[1] ;" // 1111 + " vdup.16 d28, d16[0] ;" // 0000 + " vext.16 d18, d30,d31,#3 ;" // 2333 + " vext.16 d17, d29,d30,#2 ;" // 1122 + " vext.16 d16, d28,d29,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!, {q8-q13} ;" + " vstmia r9!, {q8-q13} ;" + " vstmia r10!, {q8-q13} ;" + " vstmia r11!, {q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " orr lr, lr, lsl #16 ;" + " cmp %0, r8 ;" + " str lr, [%1],#4 ;" + " strh lr, [%1],#2 ;" + " str lr, [r9],#4 ;" + " strh lr, [r9],#2 ;" + " str lr, [r10],#4 ;" + " strh lr, [r10],#2 ;" + " str lr, [r11],#4 ;" + " strh lr, [r11],#2 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale3x_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale3x1_n16, &scale3x2_n16, &scale3x3_n16, &scale3x4_n16}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale3x1_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; +void scale3x1_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x1_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x1_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15, d19[1] ;" // 7777 - " vdup.32 q14, d19[0] ;" // 6666 - " vdup.32 q1, d18[1] ;" // 5555 - " vdup.32 q0, d18[0] ;" // 4444 - " vext.32 q13, q14,q15,#3 ;" // 6777 - " vext.32 q12, q1,q14,#2 ;" // 5566 - " vext.32 q11, q0,q1,#1 ;" // 4445 - " vdup.32 q15, d17[1] ;" // 3333 - " vdup.32 q14, d17[0] ;" // 2222 - " vdup.32 q1, d16[1] ;" // 1111 - " vdup.32 q0, d16[0] ;" // 0000 - " vext.32 q10, q14,q15,#3 ;" // 2333 - " vext.32 q9, q1,q14,#2 ;" // 1122 - " vext.32 q8, q0,q1,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!,{q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " str lr, [%1],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x2_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15, d19[1] ;" // 7777 + " vdup.32 q14, d19[0] ;" // 6666 + " vdup.32 q1, d18[1] ;" // 5555 + " vdup.32 q0, d18[0] ;" // 4444 + " vext.32 q13, q14,q15,#3 ;" // 6777 + " vext.32 q12, q1,q14,#2 ;" // 5566 + " vext.32 q11, q0,q1,#1 ;" // 4445 + " vdup.32 q15, d17[1] ;" // 3333 + " vdup.32 q14, d17[0] ;" // 2222 + " vdup.32 q1, d16[1] ;" // 1111 + " vdup.32 q0, d16[0] ;" // 0000 + " vext.32 q10, q14,q15,#3 ;" // 2333 + " vext.32 q9, q1,q14,#2 ;" // 1122 + " vext.32 q8, q0,q1,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!,{q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " str lr, [%1],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale3x2_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x2_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x2_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15, d19[1] ;" // 7777 - " vdup.32 q14, d19[0] ;" // 6666 - " vdup.32 q1, d18[1] ;" // 5555 - " vdup.32 q0, d18[0] ;" // 4444 - " vext.32 q13, q14,q15,#3 ;" // 6777 - " vext.32 q12, q1,q14,#2 ;" // 5566 - " vext.32 q11, q0,q1,#1 ;" // 4445 - " vdup.32 q15, d17[1] ;" // 3333 - " vdup.32 q14, d17[0] ;" // 2222 - " vdup.32 q1, d16[1] ;" // 1111 - " vdup.32 q0, d16[0] ;" // 0000 - " vext.32 q10, q14,q15,#3 ;" // 2333 - " vext.32 q9, q1,q14,#2 ;" // 1122 - " vext.32 q8, q0,q1,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!,{q8-q13} ;" - " vstmia r9!,{q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " str lr, [%1],#4 ;" - " vstmia r9!, {d16} ;" - " str lr, [r9],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x3_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 2 - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15, d19[1] ;" // 7777 + " vdup.32 q14, d19[0] ;" // 6666 + " vdup.32 q1, d18[1] ;" // 5555 + " vdup.32 q0, d18[0] ;" // 4444 + " vext.32 q13, q14,q15,#3 ;" // 6777 + " vext.32 q12, q1,q14,#2 ;" // 5566 + " vext.32 q11, q0,q1,#1 ;" // 4445 + " vdup.32 q15, d17[1] ;" // 3333 + " vdup.32 q14, d17[0] ;" // 2222 + " vdup.32 q1, d16[1] ;" // 1111 + " vdup.32 q0, d16[0] ;" // 0000 + " vext.32 q10, q14,q15,#3 ;" // 2333 + " vext.32 q9, q1,q14,#2 ;" // 1122 + " vext.32 q8, q0,q1,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!,{q8-q13} ;" + " vstmia r9!,{q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " str lr, [%1],#4 ;" + " vstmia r9!, {d16} ;" + " str lr, [r9],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale3x3_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x3_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x3_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15, d19[1] ;" // 7777 - " vdup.32 q14, d19[0] ;" // 6666 - " vdup.32 q1, d18[1] ;" // 5555 - " vdup.32 q0, d18[0] ;" // 4444 - " vext.32 q13, q14,q15,#3 ;" // 6777 - " vext.32 q12, q1,q14,#2 ;" // 5566 - " vext.32 q11, q0,q1,#1 ;" // 4445 - " vdup.32 q15, d17[1] ;" // 3333 - " vdup.32 q14, d17[0] ;" // 2222 - " vdup.32 q1, d16[1] ;" // 1111 - " vdup.32 q0, d16[0] ;" // 0000 - " vext.32 q10, q14,q15,#3 ;" // 2333 - " vext.32 q9, q1,q14,#2 ;" // 1122 - " vext.32 q8, q0,q1,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!,{q8-q13} ;" - " vstmia r9!,{q8-q13} ;" - " vstmia r10!,{q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " str lr, [%1],#4 ;" - " vstmia r9!, {d16} ;" - " str lr, [r9],#4 ;" - " vstmia r10!, {d16} ;" - " str lr, [r10],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x4_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 3 - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15, d19[1] ;" // 7777 + " vdup.32 q14, d19[0] ;" // 6666 + " vdup.32 q1, d18[1] ;" // 5555 + " vdup.32 q0, d18[0] ;" // 4444 + " vext.32 q13, q14,q15,#3 ;" // 6777 + " vext.32 q12, q1,q14,#2 ;" // 5566 + " vext.32 q11, q0,q1,#1 ;" // 4445 + " vdup.32 q15, d17[1] ;" // 3333 + " vdup.32 q14, d17[0] ;" // 2222 + " vdup.32 q1, d16[1] ;" // 1111 + " vdup.32 q0, d16[0] ;" // 0000 + " vext.32 q10, q14,q15,#3 ;" // 2333 + " vext.32 q9, q1,q14,#2 ;" // 1122 + " vext.32 q8, q0,q1,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!,{q8-q13} ;" + " vstmia r9!,{q8-q13} ;" + " vstmia r10!,{q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " str lr, [%1],#4 ;" + " vstmia r9!, {d16} ;" + " str lr, [r9],#4 ;" + " vstmia r10!, {d16} ;" + " str lr, [r10],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale3x4_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*3; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale3x4_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 3; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale3x4_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl*3; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15, d19[1] ;" // 7777 - " vdup.32 q14, d19[0] ;" // 6666 - " vdup.32 q1, d18[1] ;" // 5555 - " vdup.32 q0, d18[0] ;" // 4444 - " vext.32 q13, q14,q15,#3 ;" // 6777 - " vext.32 q12, q1,q14,#2 ;" // 5566 - " vext.32 q11, q0,q1,#1 ;" // 4445 - " vdup.32 q15, d17[1] ;" // 3333 - " vdup.32 q14, d17[0] ;" // 2222 - " vdup.32 q1, d16[1] ;" // 1111 - " vdup.32 q0, d16[0] ;" // 0000 - " vext.32 q10, q14,q15,#3 ;" // 2333 - " vext.32 q9, q1,q14,#2 ;" // 1122 - " vext.32 q8, q0,q1,#1 ;" // 0001 - " cmp %0, lr ;" - " vstmia %1!,{q8-q13} ;" - " vstmia r9!,{q8-q13} ;" - " vstmia r10!,{q8-q13} ;" - " vstmia r11!,{q8-q13} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " str lr, [%1],#4 ;" - " vstmia r9!, {d16} ;" - " str lr, [r9],#4 ;" - " vstmia r10!, {d16} ;" - " str lr, [r10],#4 ;" - " vstmia r11!, {d16} ;" - " str lr, [r11],#4 ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale3x_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale3x1_n32, &scale3x2_n32, &scale3x3_n32, &scale3x4_n32 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl * 3; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15, d19[1] ;" // 7777 + " vdup.32 q14, d19[0] ;" // 6666 + " vdup.32 q1, d18[1] ;" // 5555 + " vdup.32 q0, d18[0] ;" // 4444 + " vext.32 q13, q14,q15,#3 ;" // 6777 + " vext.32 q12, q1,q14,#2 ;" // 5566 + " vext.32 q11, q0,q1,#1 ;" // 4445 + " vdup.32 q15, d17[1] ;" // 3333 + " vdup.32 q14, d17[0] ;" // 2222 + " vdup.32 q1, d16[1] ;" // 1111 + " vdup.32 q0, d16[0] ;" // 0000 + " vext.32 q10, q14,q15,#3 ;" // 2333 + " vext.32 q9, q1,q14,#2 ;" // 1122 + " vext.32 q8, q0,q1,#1 ;" // 0001 + " cmp %0, lr ;" + " vstmia %1!,{q8-q13} ;" + " vstmia r9!,{q8-q13} ;" + " vstmia r10!,{q8-q13} ;" + " vstmia r11!,{q8-q13} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " str lr, [%1],#4 ;" + " vstmia r9!, {d16} ;" + " str lr, [r9],#4 ;" + " vstmia r10!, {d16} ;" + " str lr, [r10],#4 ;" + " vstmia r11!, {d16} ;" + " str lr, [r11],#4 ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale3x_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale3x1_n32, &scale3x2_n32, &scale3x3_n32, &scale3x4_n32}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale4x1_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; +void scale4x1_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x1_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x1_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31,d19[3] ;" - " vdup.16 d30,d19[2] ;" - " vdup.16 d29,d19[1] ;" - " vdup.16 d28,d19[0] ;" - " vdup.16 d27,d18[3] ;" - " vdup.16 d26,d18[2] ;" - " vdup.16 d25,d18[1] ;" - " vdup.16 d24,d18[0] ;" - " vdup.16 d23,d17[3] ;" - " vdup.16 d22,d17[2] ;" - " vdup.16 d21,d17[1] ;" - " vdup.16 d20,d17[0] ;" - " vdup.16 d19,d16[3] ;" - " vdup.16 d18,d16[2] ;" - " vdup.16 d17,d16[1] ;" - " vdup.16 d16,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " vdup.16 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x2_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31,d19[3] ;" + " vdup.16 d30,d19[2] ;" + " vdup.16 d29,d19[1] ;" + " vdup.16 d28,d19[0] ;" + " vdup.16 d27,d18[3] ;" + " vdup.16 d26,d18[2] ;" + " vdup.16 d25,d18[1] ;" + " vdup.16 d24,d18[0] ;" + " vdup.16 d23,d17[3] ;" + " vdup.16 d22,d17[2] ;" + " vdup.16 d21,d17[1] ;" + " vdup.16 d20,d17[0] ;" + " vdup.16 d19,d16[3] ;" + " vdup.16 d18,d16[2] ;" + " vdup.16 d17,d16[1] ;" + " vdup.16 d16,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " vdup.16 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale4x2_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x2_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x2_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31,d19[3] ;" - " vdup.16 d30,d19[2] ;" - " vdup.16 d29,d19[1] ;" - " vdup.16 d28,d19[0] ;" - " vdup.16 d27,d18[3] ;" - " vdup.16 d26,d18[2] ;" - " vdup.16 d25,d18[1] ;" - " vdup.16 d24,d18[0] ;" - " vdup.16 d23,d17[3] ;" - " vdup.16 d22,d17[2] ;" - " vdup.16 d21,d17[1] ;" - " vdup.16 d20,d17[0] ;" - " vdup.16 d19,d16[3] ;" - " vdup.16 d18,d16[2] ;" - " vdup.16 d17,d16[1] ;" - " vdup.16 d16,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " vstmia r9!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " vdup.16 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " vstmia r9!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x3_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 2 - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31,d19[3] ;" + " vdup.16 d30,d19[2] ;" + " vdup.16 d29,d19[1] ;" + " vdup.16 d28,d19[0] ;" + " vdup.16 d27,d18[3] ;" + " vdup.16 d26,d18[2] ;" + " vdup.16 d25,d18[1] ;" + " vdup.16 d24,d18[0] ;" + " vdup.16 d23,d17[3] ;" + " vdup.16 d22,d17[2] ;" + " vdup.16 d21,d17[1] ;" + " vdup.16 d20,d17[0] ;" + " vdup.16 d19,d16[3] ;" + " vdup.16 d18,d16[2] ;" + " vdup.16 d17,d16[1] ;" + " vdup.16 d16,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " vstmia r9!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " vdup.16 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " vstmia r9!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale4x3_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x3_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x3_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31,d19[3] ;" - " vdup.16 d30,d19[2] ;" - " vdup.16 d29,d19[1] ;" - " vdup.16 d28,d19[0] ;" - " vdup.16 d27,d18[3] ;" - " vdup.16 d26,d18[2] ;" - " vdup.16 d25,d18[1] ;" - " vdup.16 d24,d18[0] ;" - " vdup.16 d23,d17[3] ;" - " vdup.16 d22,d17[2] ;" - " vdup.16 d21,d17[1] ;" - " vdup.16 d20,d17[0] ;" - " vdup.16 d19,d16[3] ;" - " vdup.16 d18,d16[2] ;" - " vdup.16 d17,d16[1] ;" - " vdup.16 d16,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " vstmia r9!,{q8-q15} ;" - " vstmia r10!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " vdup.16 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " vstmia r9!, {d16} ;" - " vstmia r10!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x4_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 3 - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31,d19[3] ;" + " vdup.16 d30,d19[2] ;" + " vdup.16 d29,d19[1] ;" + " vdup.16 d28,d19[0] ;" + " vdup.16 d27,d18[3] ;" + " vdup.16 d26,d18[2] ;" + " vdup.16 d25,d18[1] ;" + " vdup.16 d24,d18[0] ;" + " vdup.16 d23,d17[3] ;" + " vdup.16 d22,d17[2] ;" + " vdup.16 d21,d17[1] ;" + " vdup.16 d20,d17[0] ;" + " vdup.16 d19,d16[3] ;" + " vdup.16 d18,d16[2] ;" + " vdup.16 d17,d16[1] ;" + " vdup.16 d16,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " vstmia r9!,{q8-q15} ;" + " vstmia r10!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " vdup.16 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " vstmia r9!, {d16} ;" + " vstmia r10!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale4x4_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint16_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x4_c16(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x4_c16(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes - " vdup.16 d31,d19[3] ;" - " vdup.16 d30,d19[2] ;" - " vdup.16 d29,d19[1] ;" - " vdup.16 d28,d19[0] ;" - " vdup.16 d27,d18[3] ;" - " vdup.16 d26,d18[2] ;" - " vdup.16 d25,d18[1] ;" - " vdup.16 d24,d18[0] ;" - " vdup.16 d23,d17[3] ;" - " vdup.16 d22,d17[2] ;" - " vdup.16 d21,d17[1] ;" - " vdup.16 d20,d17[0] ;" - " vdup.16 d19,d16[3] ;" - " vdup.16 d18,d16[2] ;" - " vdup.16 d17,d16[1] ;" - " vdup.16 d16,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " vstmia r9!,{q8-q15} ;" - " vstmia r10!,{q8-q15} ;" - " vstmia r11!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldrh lr, [%0],#2 ;" // rest - " vdup.16 d16, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {d16} ;" - " vstmia r9!, {d16} ;" - " vstmia r10!, {d16} ;" - " vstmia r11!, {d16} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale4x1_n16, &scale4x2_n16, &scale4x3_n16, &scale4x4_n16 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 16 pixels 32 bytes + " vdup.16 d31,d19[3] ;" + " vdup.16 d30,d19[2] ;" + " vdup.16 d29,d19[1] ;" + " vdup.16 d28,d19[0] ;" + " vdup.16 d27,d18[3] ;" + " vdup.16 d26,d18[2] ;" + " vdup.16 d25,d18[1] ;" + " vdup.16 d24,d18[0] ;" + " vdup.16 d23,d17[3] ;" + " vdup.16 d22,d17[2] ;" + " vdup.16 d21,d17[1] ;" + " vdup.16 d20,d17[0] ;" + " vdup.16 d19,d16[3] ;" + " vdup.16 d18,d16[2] ;" + " vdup.16 d17,d16[1] ;" + " vdup.16 d16,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " vstmia r9!,{q8-q15} ;" + " vstmia r10!,{q8-q15} ;" + " vstmia r11!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldrh lr, [%0],#2 ;" // rest + " vdup.16 d16, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {d16} ;" + " vstmia r9!, {d16} ;" + " vstmia r10!, {d16} ;" + " vstmia r11!, {d16} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale4x_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale4x1_n16, &scale4x2_n16, &scale4x3_n16, &scale4x4_n16}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale4x1_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; +void scale4x1_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x1_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x1_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15,d19[1] ;" - " vdup.32 q14,d19[0] ;" - " vdup.32 q13,d18[1] ;" - " vdup.32 q12,d18[0] ;" - " vdup.32 q11,d17[1] ;" - " vdup.32 q10,d17[0] ;" - " vdup.32 q9,d16[1] ;" - " vdup.32 q8,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 q8, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x2_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15,d19[1] ;" + " vdup.32 q14,d19[0] ;" + " vdup.32 q13,d18[1] ;" + " vdup.32 q12,d18[0] ;" + " vdup.32 q11,d17[1] ;" + " vdup.32 q10,d17[0] ;" + " vdup.32 q9,d16[1] ;" + " vdup.32 q8,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 q8, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale4x2_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x2_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x2_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*2 - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15,d19[1] ;" - " vdup.32 q14,d19[0] ;" - " vdup.32 q13,d18[1] ;" - " vdup.32 q12,d18[0] ;" - " vdup.32 q11,d17[1] ;" - " vdup.32 q10,d17[0] ;" - " vdup.32 q9,d16[1] ;" - " vdup.32 q8,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " vstmia r9!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 q8, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8} ;" - " vstmia r9!, {q8} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x3_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 2 - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15,d19[1] ;" + " vdup.32 q14,d19[0] ;" + " vdup.32 q13,d18[1] ;" + " vdup.32 q12,d18[0] ;" + " vdup.32 q11,d17[1] ;" + " vdup.32 q10,d17[0] ;" + " vdup.32 q9,d16[1] ;" + " vdup.32 q8,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " vstmia r9!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 q8, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8} ;" + " vstmia r9!, {q8} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale4x3_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x3_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x3_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*3 - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15,d19[1] ;" - " vdup.32 q14,d19[0] ;" - " vdup.32 q13,d18[1] ;" - " vdup.32 q12,d18[0] ;" - " vdup.32 q11,d17[1] ;" - " vdup.32 q10,d17[0] ;" - " vdup.32 q9,d16[1] ;" - " vdup.32 q8,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " vstmia r9!,{q8-q15} ;" - " vstmia r10!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 q8, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8} ;" - " vstmia r9!, {q8} ;" - " vstmia r10!, {q8} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x4_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - if (!sw||!sh) return; + uint32_t dadd = dp * 3 - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15,d19[1] ;" + " vdup.32 q14,d19[0] ;" + " vdup.32 q13,d18[1] ;" + " vdup.32 q12,d18[0] ;" + " vdup.32 q11,d17[1] ;" + " vdup.32 q10,d17[0] ;" + " vdup.32 q9,d16[1] ;" + " vdup.32 q8,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " vstmia r9!,{q8-q15} ;" + " vstmia r10!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 q8, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8} ;" + " vstmia r9!, {q8} ;" + " vstmia r10!, {q8} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", "cc"); +} + +void scale4x4_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + if (!sw || !sh) + return; uint32_t swl = sw * sizeof(uint32_t); - if (!sp) { sp = swl; } if (!dp) { dp = swl*4; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale4x4_c32(src,dst,sw,sh,sp,dw,dh,dp); return; } + if (!sp) { + sp = swl; + } + if (!dp) { + dp = swl * 4; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale4x4_c32(src, dst, sw, sh, sp, dw, dh, dp); + return; + } uint32_t swl32 = swl & ~31; uint32_t sadd = sp - swl; - uint32_t dadd = dp*4 - swl*4; - uint8_t* finofs = (uint8_t*)src + (sp*sh); - asm volatile ( - "1: add lr, %0, %2 ;" // lr = x32bytes offset - " add r8, %0, %3 ;" // r8 = lineend offset - " add r9, %1, %7 ;" // r9 = 2x line offset - " add r10, r9, %7 ;" // r10 = 3x line offset - " add r11, r10, %7 ;" // r11 = 4x line offset - " cmp %0, lr ;" - " beq 3f ;" - "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes - " vdup.32 q15,d19[1] ;" - " vdup.32 q14,d19[0] ;" - " vdup.32 q13,d18[1] ;" - " vdup.32 q12,d18[0] ;" - " vdup.32 q11,d17[1] ;" - " vdup.32 q10,d17[0] ;" - " vdup.32 q9,d16[1] ;" - " vdup.32 q8,d16[0] ;" - " cmp %0, lr ;" - " vstmia %1!,{q8-q15} ;" - " vstmia r9!,{q8-q15} ;" - " vstmia r10!,{q8-q15} ;" - " vstmia r11!,{q8-q15} ;" - " bne 2b ;" - "3: cmp %0, r8 ;" - " beq 5f ;" - "4: ldr lr, [%0],#4 ;" // rest - " vdup.32 q8, lr ;" - " cmp %0, r8 ;" - " vstmia %1!, {q8} ;" - " vstmia r9!, {q8} ;" - " vstmia r10!, {q8} ;" - " vstmia r11!, {q8} ;" - " bne 4b ;" - "5: add %0, %0, %4 ;" - " add %1, %1, %5 ;" - " cmp %0, %6 ;" - " bne 1b " - : "+r"(src), "+r"(dst) - : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) - : "r8","r9","r10","r11","lr","q8","q9","q10","q11","q12","q13","q14","q15","memory","cc" - ); -} - -void scale4x_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - void (* const func[4])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) - = { &scale4x1_n32, &scale4x2_n32, &scale4x3_n32, &scale4x4_n32 }; - if (--ymul < 4) func[ymul](src, dst, sw, sh, sp, dw, dh, dp); + uint32_t dadd = dp * 4 - swl * 4; + uint8_t *finofs = (uint8_t *)src + (sp * sh); + asm volatile("1: add lr, %0, %2 ;" // lr = x32bytes offset + " add r8, %0, %3 ;" // r8 = lineend offset + " add r9, %1, %7 ;" // r9 = 2x line offset + " add r10, r9, %7 ;" // r10 = 3x line offset + " add r11, r10, %7 ;" // r11 = 4x line offset + " cmp %0, lr ;" + " beq 3f ;" + "2: vldmia %0!,{q8-q9} ;" // 8 pixels 32 bytes + " vdup.32 q15,d19[1] ;" + " vdup.32 q14,d19[0] ;" + " vdup.32 q13,d18[1] ;" + " vdup.32 q12,d18[0] ;" + " vdup.32 q11,d17[1] ;" + " vdup.32 q10,d17[0] ;" + " vdup.32 q9,d16[1] ;" + " vdup.32 q8,d16[0] ;" + " cmp %0, lr ;" + " vstmia %1!,{q8-q15} ;" + " vstmia r9!,{q8-q15} ;" + " vstmia r10!,{q8-q15} ;" + " vstmia r11!,{q8-q15} ;" + " bne 2b ;" + "3: cmp %0, r8 ;" + " beq 5f ;" + "4: ldr lr, [%0],#4 ;" // rest + " vdup.32 q8, lr ;" + " cmp %0, r8 ;" + " vstmia %1!, {q8} ;" + " vstmia r9!, {q8} ;" + " vstmia r10!, {q8} ;" + " vstmia r11!, {q8} ;" + " bne 4b ;" + "5: add %0, %0, %4 ;" + " add %1, %1, %5 ;" + " cmp %0, %6 ;" + " bne 1b " + : "+r"(src), "+r"(dst) + : "r"(swl32), "r"(swl), "r"(sadd), "r"(dadd), "r"(finofs), "r"(dp) + : "r8", "r9", "r10", "r11", "lr", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", "memory", + "cc"); +} + +void scale4x_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + void (*const func[4])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = {&scale4x1_n32, &scale4x2_n32, &scale4x3_n32, &scale4x4_n32}; + if (--ymul < 4) + func[ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scale5x_n16line(void* src, void* dst, uint32_t swl) { - asm volatile ( - " bic r4, %2, #15 ;" // r4 = swl16 - " add r3, %0, %2 ;" // r3 = lineend offset - " add r4, %0, r4 ;" // r4 = x16bytes offset - " cmp %0, r4 ;" - " beq 2f ;" - "1: vldmia %0!, {q8} ;" // 8 pixels 16 bytes - " vdup.16 d25, d17[3] ;" // 7777 - " vdup.16 d27, d17[2] ;" // 6666 - " vdup.16 d26, d17[1] ;" // 5555 - " vdup.16 d21, d17[0] ;" // 4444 - " vext.16 d24, d27,d25,#1 ;" // 6667 - " vext.16 d23, d26,d27,#2 ;" // 5566 - " vext.16 d22, d21,d26,#3 ;" // 4555 - " vdup.16 d20, d16[3] ;" // 3333 - " vdup.16 d27, d16[2] ;" // 2222 - " vdup.16 d26, d16[1] ;" // 1111 - " vdup.16 d16, d16[0] ;" // 0000 - " vext.16 d19, d27,d20,#1 ;" // 2223 - " vext.16 d18, d26,d27,#2 ;" // 1122 - " vext.16 d17, d16,d26,#3 ;" // 0111 - " cmp %0, r4 ;" - " vstmia %1!, {q8-q12} ;" - " bne 1b ;" - "2: cmp %0, r3 ;" - " beq 4f ;" - "3: ldrh r4, [%0],#2 ;" // rest - " orr r4, r4, lsl #16 ;" - " cmp %0, r3 ;" - " str r4, [%1],#4 ;" - " str r4, [%1],#4 ;" - " strh r4, [%1],#2 ;" - " bne 3b ;" - "4: " - : "+r"(src), "+r"(dst) - : "r"(swl) - : "r3","r4","q8","q9","q10","q11","q12","q13","memory","cc" - ); -} - -void scale5x_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; +void scale5x_n16line(void *src, void *dst, uint32_t swl) +{ + asm volatile(" bic r4, %2, #15 ;" // r4 = swl16 + " add r3, %0, %2 ;" // r3 = lineend offset + " add r4, %0, r4 ;" // r4 = x16bytes offset + " cmp %0, r4 ;" + " beq 2f ;" + "1: vldmia %0!, {q8} ;" // 8 pixels 16 bytes + " vdup.16 d25, d17[3] ;" // 7777 + " vdup.16 d27, d17[2] ;" // 6666 + " vdup.16 d26, d17[1] ;" // 5555 + " vdup.16 d21, d17[0] ;" // 4444 + " vext.16 d24, d27,d25,#1 ;" // 6667 + " vext.16 d23, d26,d27,#2 ;" // 5566 + " vext.16 d22, d21,d26,#3 ;" // 4555 + " vdup.16 d20, d16[3] ;" // 3333 + " vdup.16 d27, d16[2] ;" // 2222 + " vdup.16 d26, d16[1] ;" // 1111 + " vdup.16 d16, d16[0] ;" // 0000 + " vext.16 d19, d27,d20,#1 ;" // 2223 + " vext.16 d18, d26,d27,#2 ;" // 1122 + " vext.16 d17, d16,d26,#3 ;" // 0111 + " cmp %0, r4 ;" + " vstmia %1!, {q8-q12} ;" + " bne 1b ;" + "2: cmp %0, r3 ;" + " beq 4f ;" + "3: ldrh r4, [%0],#2 ;" // rest + " orr r4, r4, lsl #16 ;" + " cmp %0, r3 ;" + " str r4, [%1],#4 ;" + " str r4, [%1],#4 ;" + " strh r4, [%1],#2 ;" + " bne 3b ;" + "4: " + : "+r"(src), "+r"(dst) + : "r"(swl) + : "r3", "r4", "q8", "q9", "q10", "q11", "q12", "q13", "memory", "cc"); +} + +void scale5x_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; uint32_t swl = sw * sizeof(uint16_t); - uint32_t dwl = swl*5; - if (!sp) { sp = swl; } if (!dp) { dp = dwl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale5x_c16(src,dst,sw,sh,sp,dw,dh,dp,ymul); return; } - void* __restrict dstsrc; - for (; sh>0; sh--, src=(uint8_t*)src+sp) { + uint32_t dwl = swl * 5; + if (!sp) { + sp = swl; + } + if (!dp) { + dp = dwl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale5x_c16(src, dst, sw, sh, sp, dw, dh, dp, ymul); + return; + } + void *__restrict dstsrc; + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { scale5x_n16line(src, dst, swl); - dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy_neon(dst, dstsrc, dwl); - } -} - -void scale5x1_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale5x2_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale5x3_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale5x4_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale5x5_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 5); } - -void scale5x_n32line(void* src, void* dst, uint32_t swl) { - asm volatile ( - " bic r4, %2, #15 ;" // r4 = swl16 - " add r3, %0, %2 ;" // r3 = lineend offset - " add r4, %0, r4 ;" // r4 = x16bytes offset - " cmp %0, r4 ;" - " beq 2f ;" - "1: vldmia %0!,{q8} ;" // 4 pixels 16 bytes - " vdup.32 q12, d17[1] ;" // 3333 - " vdup.32 q14, d17[0] ;" // 2222 - " vdup.32 q13, d16[1] ;" // 1111 - " vdup.32 q8, d16[0] ;" // 0000 - " vext.32 q11, q14,q12,#1 ;" // 2223 - " vext.32 q10, q13,q14,#2 ;" // 1122 - " vext.32 q9, q8,q13,#3 ;" // 0111 - " cmp %0, r4 ;" - " vstmia %1!,{q8-q12} ;" - " bne 1b ;" - "2: cmp %0, r3 ;" - " beq 4f ;" - "3: ldr r4, [%0],#4 ;" // rest - " vdup.32 q8, r4 ;" - " cmp %0, r3 ;" - " vstmia %1!, {q8} ;" - " str r4, [%1],#4 ;" - " bne 3b ;" - "4: " - : "+r"(src), "+r"(dst) - : "r"(swl) - : "r3","r4","q8","q9","q10","q11","q12","q13","q14","memory","cc" - ); -} - -void scale5x_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; + dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy_neon(dst, dstsrc, dwl); + } +} + +void scale5x1_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale5x2_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale5x3_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale5x4_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale5x5_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n16(src, dst, sw, sh, sp, dw, dh, dp, 5); +} + +void scale5x_n32line(void *src, void *dst, uint32_t swl) +{ + asm volatile(" bic r4, %2, #15 ;" // r4 = swl16 + " add r3, %0, %2 ;" // r3 = lineend offset + " add r4, %0, r4 ;" // r4 = x16bytes offset + " cmp %0, r4 ;" + " beq 2f ;" + "1: vldmia %0!,{q8} ;" // 4 pixels 16 bytes + " vdup.32 q12, d17[1] ;" // 3333 + " vdup.32 q14, d17[0] ;" // 2222 + " vdup.32 q13, d16[1] ;" // 1111 + " vdup.32 q8, d16[0] ;" // 0000 + " vext.32 q11, q14,q12,#1 ;" // 2223 + " vext.32 q10, q13,q14,#2 ;" // 1122 + " vext.32 q9, q8,q13,#3 ;" // 0111 + " cmp %0, r4 ;" + " vstmia %1!,{q8-q12} ;" + " bne 1b ;" + "2: cmp %0, r3 ;" + " beq 4f ;" + "3: ldr r4, [%0],#4 ;" // rest + " vdup.32 q8, r4 ;" + " cmp %0, r3 ;" + " vstmia %1!, {q8} ;" + " str r4, [%1],#4 ;" + " bne 3b ;" + "4: " + : "+r"(src), "+r"(dst) + : "r"(swl) + : "r3", "r4", "q8", "q9", "q10", "q11", "q12", "q13", "q14", "memory", "cc"); +} + +void scale5x_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; uint32_t swl = sw * sizeof(uint32_t); - uint32_t dwl = swl*5; - if (!sp) { sp = swl; } if (!dp) { dp = dwl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale5x_c32(src,dst,sw,sh,sp,dw,dh,dp,ymul); return; } - void* __restrict dstsrc; - for (; sh>0; sh--, src=(uint8_t*)src+sp) { + uint32_t dwl = swl * 5; + if (!sp) { + sp = swl; + } + if (!dp) { + dp = dwl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale5x_c32(src, dst, sw, sh, sp, dw, dh, dp, ymul); + return; + } + void *__restrict dstsrc; + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { scale5x_n32line(src, dst, swl); - dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy_neon(dst, dstsrc, dwl); - } -} - -void scale5x1_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale5x2_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale5x3_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale5x4_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale5x5_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 5); } - -void scale6x_n16line(void* src, void* dst, uint32_t swl) { - asm volatile ( - " bic r4, %2, #15 ;" // r4 = swl16 - " add r3, %0, %2 ;" // r3 = lineend offset - " add r4, %0, r4 ;" // r4 = x16bytes offset - " cmp %0, r4 ;" - " beq 2f ;" - "1: vldmia %0!, {q8} ;" // 8 pixels 16 bytes - " vdup.16 d27, d17[3] ;" // 7777 - " vdup.16 d25, d17[2] ;" // 6666 - " vdup.16 d24, d17[1] ;" // 5555 - " vdup.16 d22, d17[0] ;" // 4444 - " vext.16 d26, d25,d27,#2 ;" // 6677 - " vext.16 d23, d22,d24,#2 ;" // 4455 - " vdup.16 d21, d16[3] ;" // 3333 - " vdup.16 d19, d16[2] ;" // 2222 - " vdup.16 d18, d16[1] ;" // 1111 - " vdup.16 d16, d16[0] ;" // 0000 - " vext.16 d20, d19,d21,#2 ;" // 2233 - " vext.16 d17, d16,d18,#2 ;" // 0011 - " cmp %0, r4 ;" - " vstmia %1!, {q8-q13} ;" - " bne 1b ;" - "2: cmp %0, r3 ;" - " beq 4f ;" - "3: ldrh r4, [%0],#2 ;" // rest - " orr r4, r4, lsl #16 ;" - " vdup.32 d16, r4 ;" - " cmp %0, r3 ;" - " vstmia %1!, {d16} ;" - " str r4, [%1],#4 ;" - " bne 3b ;" - "4: " - : "+r"(src), "+r"(dst) - : "r"(swl) - : "r3","r4","q8","q9","q10","q11","q12","q13","memory","cc" - ); -} - -void scale6x_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; + dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy_neon(dst, dstsrc, dwl); + } +} + +void scale5x1_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale5x2_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale5x3_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale5x4_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale5x5_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale5x_n32(src, dst, sw, sh, sp, dw, dh, dp, 5); +} + +void scale6x_n16line(void *src, void *dst, uint32_t swl) +{ + asm volatile(" bic r4, %2, #15 ;" // r4 = swl16 + " add r3, %0, %2 ;" // r3 = lineend offset + " add r4, %0, r4 ;" // r4 = x16bytes offset + " cmp %0, r4 ;" + " beq 2f ;" + "1: vldmia %0!, {q8} ;" // 8 pixels 16 bytes + " vdup.16 d27, d17[3] ;" // 7777 + " vdup.16 d25, d17[2] ;" // 6666 + " vdup.16 d24, d17[1] ;" // 5555 + " vdup.16 d22, d17[0] ;" // 4444 + " vext.16 d26, d25,d27,#2 ;" // 6677 + " vext.16 d23, d22,d24,#2 ;" // 4455 + " vdup.16 d21, d16[3] ;" // 3333 + " vdup.16 d19, d16[2] ;" // 2222 + " vdup.16 d18, d16[1] ;" // 1111 + " vdup.16 d16, d16[0] ;" // 0000 + " vext.16 d20, d19,d21,#2 ;" // 2233 + " vext.16 d17, d16,d18,#2 ;" // 0011 + " cmp %0, r4 ;" + " vstmia %1!, {q8-q13} ;" + " bne 1b ;" + "2: cmp %0, r3 ;" + " beq 4f ;" + "3: ldrh r4, [%0],#2 ;" // rest + " orr r4, r4, lsl #16 ;" + " vdup.32 d16, r4 ;" + " cmp %0, r3 ;" + " vstmia %1!, {d16} ;" + " str r4, [%1],#4 ;" + " bne 3b ;" + "4: " + : "+r"(src), "+r"(dst) + : "r"(swl) + : "r3", "r4", "q8", "q9", "q10", "q11", "q12", "q13", "memory", "cc"); +} + +void scale6x_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; uint32_t swl = sw * sizeof(uint16_t); - uint32_t dwl = swl*6; - if (!sp) { sp = swl; } if (!dp) { dp = dwl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale6x_c16(src,dst,sw,sh,sp,dw,dh,dp,ymul); return; } - void* __restrict dstsrc; - for (; sh>0; sh--, src=(uint8_t*)src+sp) { + uint32_t dwl = swl * 6; + if (!sp) { + sp = swl; + } + if (!dp) { + dp = dwl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale6x_c16(src, dst, sw, sh, sp, dw, dh, dp, ymul); + return; + } + void *__restrict dstsrc; + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { scale6x_n16line(src, dst, swl); - dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy_neon(dst, dstsrc, dwl); - } -} - -void scale6x1_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale6x2_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale6x3_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale6x4_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale6x5_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 5); } -void scale6x6_n16(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 6); } - -void scale6x_n32line(void* src, void* dst, uint32_t swl) { - asm volatile ( - " bic r4, %2, #15 ;" // r4 = swl16 - " add r3, %0, %2 ;" // r3 = lineend offset - " add r4, %0, r4 ;" // r4 = x16bytes offset - " cmp %0, r4 ;" - " beq 2f ;" - "1: vldmia %0!,{q8} ;" // 4 pixels 16 bytes - " vdup.32 q13, d17[1] ;" // 3333 - " vdup.32 q11, d17[0] ;" // 2222 - " vdup.32 q10, d16[1] ;" // 1111 - " vdup.32 q8, d16[0] ;" // 0000 - " vext.32 q12, q11,q13,#2 ;" // 2233 - " vext.32 q9, q8,q10,#2 ;" // 0011 - " cmp %0, r4 ;" - " vstmia %1!,{q8-q13} ;" - " bne 1b ;" - "2: cmp %0, r3 ;" - " beq 4f ;" - "3: ldr r4, [%0],#4 ;" // rest - " vdup.32 q8, r4 ;" - " vmov d18, d16 ;" - " cmp %0, r3 ;" - " vstmia %1!, {d16-d18} ;" - " bne 3b ;" - "4: " - : "+r"(src), "+r"(dst) - : "r"(swl) - : "r3","r4","q8","q9","q10","q11","q12","q13","memory","cc" - ); -} - -void scale6x_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp, uint32_t ymul) { - if (!sw||!sh||!ymul) return; + dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy_neon(dst, dstsrc, dwl); + } +} + +void scale6x1_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale6x2_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale6x3_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale6x4_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale6x5_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 5); +} +void scale6x6_n16(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n16(src, dst, sw, sh, sp, dw, dh, dp, 6); +} + +void scale6x_n32line(void *src, void *dst, uint32_t swl) +{ + asm volatile(" bic r4, %2, #15 ;" // r4 = swl16 + " add r3, %0, %2 ;" // r3 = lineend offset + " add r4, %0, r4 ;" // r4 = x16bytes offset + " cmp %0, r4 ;" + " beq 2f ;" + "1: vldmia %0!,{q8} ;" // 4 pixels 16 bytes + " vdup.32 q13, d17[1] ;" // 3333 + " vdup.32 q11, d17[0] ;" // 2222 + " vdup.32 q10, d16[1] ;" // 1111 + " vdup.32 q8, d16[0] ;" // 0000 + " vext.32 q12, q11,q13,#2 ;" // 2233 + " vext.32 q9, q8,q10,#2 ;" // 0011 + " cmp %0, r4 ;" + " vstmia %1!,{q8-q13} ;" + " bne 1b ;" + "2: cmp %0, r3 ;" + " beq 4f ;" + "3: ldr r4, [%0],#4 ;" // rest + " vdup.32 q8, r4 ;" + " vmov d18, d16 ;" + " cmp %0, r3 ;" + " vstmia %1!, {d16-d18} ;" + " bne 3b ;" + "4: " + : "+r"(src), "+r"(dst) + : "r"(swl) + : "r3", "r4", "q8", "q9", "q10", "q11", "q12", "q13", "memory", "cc"); +} + +void scale6x_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp, uint32_t ymul) +{ + if (!sw || !sh || !ymul) + return; uint32_t swl = sw * sizeof(uint32_t); - uint32_t dwl = swl*6; - if (!sp) { sp = swl; } if (!dp) { dp = dwl; } - if ( ((uintptr_t)src&3)||((uintptr_t)dst&3)||(sp&3)||(dp&3) ) { scale6x_c32(src,dst,sw,sh,sp,dw,dh,dp,ymul); return; } - void* __restrict dstsrc; - for (; sh>0; sh--, src=(uint8_t*)src+sp) { + uint32_t dwl = swl * 6; + if (!sp) { + sp = swl; + } + if (!dp) { + dp = dwl; + } + if (((uintptr_t)src & 3) || ((uintptr_t)dst & 3) || (sp & 3) || (dp & 3)) { + scale6x_c32(src, dst, sw, sh, sp, dw, dh, dp, ymul); + return; + } + void *__restrict dstsrc; + for (; sh > 0; sh--, src = (uint8_t *)src + sp) { scale6x_n32line(src, dst, swl); - dstsrc = dst; dst = (uint8_t*)dst+dp; - for (uint32_t i=ymul-1; i>0; i--, dst=(uint8_t*)dst+dp) memcpy_neon(dst, dstsrc, dwl); - } -} - -void scale6x1_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 1); } -void scale6x2_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 2); } -void scale6x3_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 3); } -void scale6x4_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 4); } -void scale6x5_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 5); } -void scale6x6_n32(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 6); } - -void scaler_n16(uint32_t xmul, uint32_t ymul, void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - void (* const func[6][8])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) = { - { &scale1x1_n16, &scale1x2_n16, &scale1x3_n16, &scale1x4_n16, &dummy, &dummy, &dummy, &dummy }, - { &scale2x1_n16, &scale2x2_n16, &scale2x3_n16, &scale2x4_n16, &dummy, &dummy, &dummy, &dummy }, - { &scale3x1_n16, &scale3x2_n16, &scale3x3_n16, &scale3x4_n16, &dummy, &dummy, &dummy, &dummy }, - { &scale4x1_n16, &scale4x2_n16, &scale4x3_n16, &scale4x4_n16, &dummy, &dummy, &dummy, &dummy }, - { &scale5x1_n16, &scale5x2_n16, &scale5x3_n16, &scale5x4_n16, &scale5x5_n16, &dummy, &dummy, &dummy }, - { &scale6x1_n16, &scale6x2_n16, &scale6x3_n16, &scale6x4_n16, &scale6x5_n16, &scale6x6_n16, &dummy, &dummy } - }; - if ((--xmul < 6)&&(--ymul < 6)) func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); + dstsrc = dst; + dst = (uint8_t *)dst + dp; + for (uint32_t i = ymul - 1; i > 0; i--, dst = (uint8_t *)dst + dp) + memcpy_neon(dst, dstsrc, dwl); + } +} + +void scale6x1_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 1); +} +void scale6x2_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 2); +} +void scale6x3_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 3); +} +void scale6x4_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 4); +} +void scale6x5_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 5); +} +void scale6x6_n32(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ + scale6x_n32(src, dst, sw, sh, sp, dw, dh, dp, 6); +} + +void scaler_n16(uint32_t xmul, uint32_t ymul, void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, + uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) +{ + void (*const func[6][8])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = { + {&scale1x1_n16, &scale1x2_n16, &scale1x3_n16, &scale1x4_n16, &dummy, &dummy, &dummy, &dummy}, + {&scale2x1_n16, &scale2x2_n16, &scale2x3_n16, &scale2x4_n16, &dummy, &dummy, &dummy, &dummy}, + {&scale3x1_n16, &scale3x2_n16, &scale3x3_n16, &scale3x4_n16, &dummy, &dummy, &dummy, &dummy}, + {&scale4x1_n16, &scale4x2_n16, &scale4x3_n16, &scale4x4_n16, &dummy, &dummy, &dummy, &dummy}, + {&scale5x1_n16, &scale5x2_n16, &scale5x3_n16, &scale5x4_n16, &scale5x5_n16, &dummy, &dummy, &dummy}, + {&scale6x1_n16, &scale6x2_n16, &scale6x3_n16, &scale6x4_n16, &scale6x5_n16, &scale6x6_n16, &dummy, &dummy}}; + if ((--xmul < 6) && (--ymul < 6)) + func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scaler_n32(uint32_t xmul, uint32_t ymul, void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - void (* const func[6][8])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) = { - { &scale1x1_n32, &scale1x2_n32, &scale1x3_n32, &scale1x4_n32, &dummy, &dummy, &dummy, &dummy }, - { &scale2x1_n32, &scale2x2_n32, &scale2x3_n32, &scale2x4_n32, &dummy, &dummy, &dummy, &dummy }, - { &scale3x1_n32, &scale3x2_n32, &scale3x3_n32, &scale3x4_n32, &dummy, &dummy, &dummy, &dummy }, - { &scale4x1_n32, &scale4x2_n32, &scale4x3_n32, &scale4x4_n32, &dummy, &dummy, &dummy, &dummy }, - { &scale5x1_n32, &scale5x2_n32, &scale5x3_n32, &scale5x4_n32, &scale5x5_n32, &dummy, &dummy, &dummy }, - { &scale6x1_n32, &scale6x2_n32, &scale6x3_n32, &scale6x4_n32, &scale6x5_n32, &scale6x6_n32, &dummy, &dummy } - }; - if ((--xmul < 6)&&(--ymul < 6)) func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); +void scaler_n32(uint32_t xmul, uint32_t ymul, void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, + uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) +{ + void (*const func[6][8])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = { + {&scale1x1_n32, &scale1x2_n32, &scale1x3_n32, &scale1x4_n32, &dummy, &dummy, &dummy, &dummy}, + {&scale2x1_n32, &scale2x2_n32, &scale2x3_n32, &scale2x4_n32, &dummy, &dummy, &dummy, &dummy}, + {&scale3x1_n32, &scale3x2_n32, &scale3x3_n32, &scale3x4_n32, &dummy, &dummy, &dummy, &dummy}, + {&scale4x1_n32, &scale4x2_n32, &scale4x3_n32, &scale4x4_n32, &dummy, &dummy, &dummy, &dummy}, + {&scale5x1_n32, &scale5x2_n32, &scale5x3_n32, &scale5x4_n32, &scale5x5_n32, &dummy, &dummy, &dummy}, + {&scale6x1_n32, &scale6x2_n32, &scale6x3_n32, &scale6x4_n32, &scale6x5_n32, &scale6x6_n32, &dummy, &dummy}}; + if ((--xmul < 6) && (--ymul < 6)) + func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } #endif -void scaler_c16(uint32_t xmul, uint32_t ymul, void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - void (* const func[6][8])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) = { - { &scale1x1_c16, &scale1x2_c16, &scale1x3_c16, &scale1x4_c16, &dummy, &dummy, &dummy, &dummy }, - { &scale2x1_c16, &scale2x2_c16, &scale2x3_c16, &scale2x4_c16, &dummy, &dummy, &dummy, &dummy }, - { &scale3x1_c16, &scale3x2_c16, &scale3x3_c16, &scale3x4_c16, &dummy, &dummy, &dummy, &dummy }, - { &scale4x1_c16, &scale4x2_c16, &scale4x3_c16, &scale4x4_c16, &dummy, &dummy, &dummy, &dummy }, - { &scale5x1_c16, &scale5x2_c16, &scale5x3_c16, &scale5x4_c16, &scale5x5_c16, &dummy, &dummy, &dummy }, - { &scale6x1_c16, &scale6x2_c16, &scale6x3_c16, &scale6x4_c16, &scale6x5_c16, &scale6x6_c16, &dummy, &dummy } - }; - if ((--xmul < 6)&&(--ymul < 6)) func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); +void scaler_c16(uint32_t xmul, uint32_t ymul, void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, + uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) +{ + void (*const func[6][8])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = { + {&scale1x1_c16, &scale1x2_c16, &scale1x3_c16, &scale1x4_c16, &dummy, &dummy, &dummy, &dummy}, + {&scale2x1_c16, &scale2x2_c16, &scale2x3_c16, &scale2x4_c16, &dummy, &dummy, &dummy, &dummy}, + {&scale3x1_c16, &scale3x2_c16, &scale3x3_c16, &scale3x4_c16, &dummy, &dummy, &dummy, &dummy}, + {&scale4x1_c16, &scale4x2_c16, &scale4x3_c16, &scale4x4_c16, &dummy, &dummy, &dummy, &dummy}, + {&scale5x1_c16, &scale5x2_c16, &scale5x3_c16, &scale5x4_c16, &scale5x5_c16, &dummy, &dummy, &dummy}, + {&scale6x1_c16, &scale6x2_c16, &scale6x3_c16, &scale6x4_c16, &scale6x5_c16, &scale6x6_c16, &dummy, &dummy}}; + if ((--xmul < 6) && (--ymul < 6)) + func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } -void scaler_c32(uint32_t xmul, uint32_t ymul, void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { - void (* const func[6][8])(void* __restrict, void* __restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) = { - { &scale1x1_c32, &scale1x2_c32, &scale1x3_c32, &scale1x4_c32, &dummy, &dummy, &dummy, &dummy }, - { &scale2x1_c32, &scale2x2_c32, &scale2x3_c32, &scale2x4_c32, &dummy, &dummy, &dummy, &dummy }, - { &scale3x1_c32, &scale3x2_c32, &scale3x3_c32, &scale3x4_c32, &dummy, &dummy, &dummy, &dummy }, - { &scale4x1_c32, &scale4x2_c32, &scale4x3_c32, &scale4x4_c32, &dummy, &dummy, &dummy, &dummy }, - { &scale5x1_c32, &scale5x2_c32, &scale5x3_c32, &scale5x4_c32, &scale5x5_c32, &dummy, &dummy, &dummy }, - { &scale6x1_c32, &scale6x2_c32, &scale6x3_c32, &scale6x4_c32, &scale6x5_c32, &scale6x6_c32, &dummy, &dummy } - }; - if ((--xmul < 6)&&(--ymul < 6)) func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); +void scaler_c32(uint32_t xmul, uint32_t ymul, void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, + uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) +{ + void (*const func[6][8])(void *__restrict, void *__restrict, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, + uint32_t) = { + {&scale1x1_c32, &scale1x2_c32, &scale1x3_c32, &scale1x4_c32, &dummy, &dummy, &dummy, &dummy}, + {&scale2x1_c32, &scale2x2_c32, &scale2x3_c32, &scale2x4_c32, &dummy, &dummy, &dummy, &dummy}, + {&scale3x1_c32, &scale3x2_c32, &scale3x3_c32, &scale3x4_c32, &dummy, &dummy, &dummy, &dummy}, + {&scale4x1_c32, &scale4x2_c32, &scale4x3_c32, &scale4x4_c32, &dummy, &dummy, &dummy, &dummy}, + {&scale5x1_c32, &scale5x2_c32, &scale5x3_c32, &scale5x4_c32, &scale5x5_c32, &dummy, &dummy, &dummy}, + {&scale6x1_c32, &scale6x2_c32, &scale6x3_c32, &scale6x4_c32, &scale6x5_c32, &scale6x6_c32, &dummy, &dummy}}; + if ((--xmul < 6) && (--ymul < 6)) + func[xmul][ymul](src, dst, sw, sh, sp, dw, dh, dp); return; } // from gambatte-dms -//from RGB565 +// from RGB565 #define cR(A) (((A) & 0xf800) >> 11) #define cG(A) (((A) & 0x7e0) >> 5) #define cB(A) ((A) & 0x1f) -//to RGB565 -#define Weight2_3(A, B) (((((cR(A) << 1) + (cR(B) * 3)) / 5) & 0x1f) << 11 | ((((cG(A) << 1) + (cG(B) * 3)) / 5) & 0x3f) << 5 | ((((cB(A) << 1) + (cB(B) * 3)) / 5) & 0x1f)) -#define Weight3_1(A, B) ((((cR(B) + (cR(A) * 3)) >> 2) & 0x1f) << 11 | (((cG(B) + (cG(A) * 3)) >> 2) & 0x3f) << 5 | (((cB(B) + (cB(A) * 3)) >> 2) & 0x1f)) -#define Weight3_2(A, B) (((((cR(B) << 1) + (cR(A) * 3)) / 5) & 0x1f) << 11 | ((((cG(B) << 1) + (cG(A) * 3)) / 5) & 0x3f) << 5 | ((((cB(B) << 1) + (cB(A) * 3)) / 5) & 0x1f)) +// to RGB565 +#define Weight2_3(A, B) \ + (((((cR(A) << 1) + (cR(B) * 3)) / 5) & 0x1f) << 11 | ((((cG(A) << 1) + (cG(B) * 3)) / 5) & 0x3f) << 5 | \ + ((((cB(A) << 1) + (cB(B) * 3)) / 5) & 0x1f)) +#define Weight3_1(A, B) \ + ((((cR(B) + (cR(A) * 3)) >> 2) & 0x1f) << 11 | (((cG(B) + (cG(A) * 3)) >> 2) & 0x3f) << 5 | \ + (((cB(B) + (cB(A) * 3)) >> 2) & 0x1f)) +#define Weight3_2(A, B) \ + (((((cR(B) << 1) + (cR(A) * 3)) / 5) & 0x1f) << 11 | ((((cG(B) << 1) + (cG(A) * 3)) / 5) & 0x3f) << 5 | \ + ((((cB(B) << 1) + (cB(A) * 3)) / 5) & 0x1f)) #define MIN(a, b) (a) < (b) ? (a) : (b) -void scale1x_line(void* __restrict src, void* __restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, uint32_t dh, uint32_t dp) { +void scale1x_line(void *__restrict src, void *__restrict dst, uint32_t sw, uint32_t sh, uint32_t sp, uint32_t dw, + uint32_t dh, uint32_t dp) +{ // pitch of src image not src buffer! - // eg. gb has a 160 pixel wide image but + // eg. gb has a 160 pixel wide image but // gambatte uses a 256 pixel wide buffer - // (only matters when using memcpy) - int ip = sw * FIXED_BPP; + // (only matters when using memcpy) + int ip = sw * FIXED_BPP; int src_stride = 2 * sp / FIXED_BPP; int dst_stride = 2 * dp / FIXED_BPP; int cpy_pitch = MIN(ip, dp); - + uint16_t k = 0x0000; - uint16_t* restrict src_row = (uint16_t*)src; - uint16_t* restrict dst_row = (uint16_t*)dst; - for (int y=0; yformat->Amask) SDL_SetSurfaceAlphaMod(surface, value); \ - surface->flags |= SDL_SRCALPHA; \ - SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND); \ - } else { \ - if (!surface->format->Amask) SDL_SetSurfaceAlphaMod(surface, 255); \ - surface->flags &= ~SDL_SRCALPHA; \ - SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); \ - } \ -} while(0); +#define SDLX_SetAlpha(surface, flags_, value) \ + do { \ + if (flags_ & SDL_SRCALPHA) { \ + if (!surface->format->Amask) \ + SDL_SetSurfaceAlphaMod(surface, value); \ + surface->flags |= SDL_SRCALPHA; \ + SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND); \ + } else { \ + if (!surface->format->Amask) \ + SDL_SetSurfaceAlphaMod(surface, 255); \ + surface->flags &= ~SDL_SRCALPHA; \ + SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); \ + } \ + } while (0); /////////////////////////////// diff --git a/workspace/all/common/utils.c b/workspace/all/common/utils.c index 90640b444..58e40cfd7 100644 --- a/workspace/all/common/utils.c +++ b/workspace/all/common/utils.c @@ -12,41 +12,51 @@ /////////////////////////////////////// -int prefixMatch(char* pre, const char* str) { - return (strncasecmp(pre,str,strlen(pre))==0); +int prefixMatch(char *pre, const char *str) +{ + return (strncasecmp(pre, str, strlen(pre)) == 0); } -int suffixMatch(char* suf, const char* str) { +int suffixMatch(char *suf, const char *str) +{ int len = strlen(suf); - int offset = strlen(str)-len; - return (offset>=0 && strncasecmp(suf, str+offset, len)==0); + int offset = strlen(str) - len; + return (offset >= 0 && strncasecmp(suf, str + offset, len) == 0); } -int exactMatch(const char* str1, const char* str2) { - if (!str1 || !str2) return 0; // NULL isn't safe here +int exactMatch(const char *str1, const char *str2) +{ + if (!str1 || !str2) + return 0; // NULL isn't safe here int len1 = strlen(str1); - if (len1!=strlen(str2)) return 0; - return (strncmp(str1,str2,len1)==0); + if (len1 != strlen(str2)) + return 0; + return (strncmp(str1, str2, len1) == 0); } -int containsString(char* haystack, char* needle) { +int containsString(char *haystack, char *needle) +{ return strcasestr(haystack, needle) != NULL; } -int hide(char* file_name) { - return file_name[0]=='.' || suffixMatch(".disabled", file_name) || exactMatch("map.txt", file_name); +int hide(char *file_name) +{ + return file_name[0] == '.' || suffixMatch(".disabled", file_name) || exactMatch("map.txt", file_name); } char *splitString(char *str, const char *delim) { - char *p = strstr(str, delim); - if (p == NULL) - return NULL; // delimiter not found - *p = '\0'; // terminate string after head - return p + strlen(delim); // return tail substring + char *p = strstr(str, delim); + if (p == NULL) + return NULL; // delimiter not found + *p = '\0'; // terminate string after head + return p + strlen(delim); // return tail substring } -void truncateString(char *string, size_t max_len) { +void truncateString(char *string, size_t max_len) +{ size_t len = strlen(string) + 1; - if (len <= max_len) return; + if (len <= max_len) + return; strncpy(&string[max_len - 4], "...\0", 4); } -void wrapString(char *string, size_t max_len, size_t max_lines) { +void wrapString(char *string, size_t max_len, size_t max_lines) +{ char *line = string; for (size_t i = 1; i < max_lines; i++) { @@ -54,10 +64,11 @@ void wrapString(char *string, size_t max_len, size_t max_lines) { char *prev; do { prev = p; - p = strchr(prev+1, ' '); + p = strchr(prev + 1, ' '); } while (p && p - line < (int)max_len); - if (!p && strlen(line) < max_len) break; + if (!p && strlen(line) < max_len) + break; if (prev && prev != line) { line = prev + 1; @@ -70,293 +81,298 @@ void wrapString(char *string, size_t max_len, size_t max_lines) { // This one does not modify the input, cause we arent savages char *replaceString2(const char *orig, char *rep, char *with) { - const char *ins; // the next insert point - char *tmp; // varies - int len_rep; // length of rep (the string to remove) - int len_with; // length of with (the string to replace rep with) - int len_front; // distance between rep and end of last rep - int count; // number of replacements - - // sanity checks and initialization - if (!orig || !rep) - return NULL; - len_rep = strlen(rep); - if (len_rep == 0) - return NULL; // empty rep causes infinite loop during count - if (!with) - with = ""; - len_with = strlen(with); - - // count the number of replacements needed - ins = orig; - for (count = 0; (tmp = strstr(ins, rep)); ++count) - ins = tmp + len_rep; - - char *result = - (char *)malloc(strlen(orig) + (len_with - len_rep) * count + 1); - tmp = result; - - if (!result) - return NULL; - - // first time through the loop, all the variable are set correctly - // from here on, - // tmp points to the end of the result string - // ins points to the next occurrence of rep in orig - // orig points to the remainder of orig after "end of rep" - while (count--) { - ins = strstr(orig, rep); - len_front = ins - orig; - tmp = strncpy(tmp, orig, len_front) + len_front; - tmp = strcpy(tmp, with) + len_with; - orig += len_front + len_rep; // move to next "end of rep" - } - strcpy(tmp, orig); - return result; + const char *ins; // the next insert point + char *tmp; // varies + int len_rep; // length of rep (the string to remove) + int len_with; // length of with (the string to replace rep with) + int len_front; // distance between rep and end of last rep + int count; // number of replacements + + // sanity checks and initialization + if (!orig || !rep) + return NULL; + len_rep = strlen(rep); + if (len_rep == 0) + return NULL; // empty rep causes infinite loop during count + if (!with) + with = ""; + len_with = strlen(with); + + // count the number of replacements needed + ins = orig; + for (count = 0; (tmp = strstr(ins, rep)); ++count) + ins = tmp + len_rep; + + char *result = (char *)malloc(strlen(orig) + (len_with - len_rep) * count + 1); + tmp = result; + + if (!result) + return NULL; + + // first time through the loop, all the variable are set correctly + // from here on, + // tmp points to the end of the result string + // ins points to the next occurrence of rep in orig + // orig points to the remainder of orig after "end of rep" + while (count--) { + ins = strstr(orig, rep); + len_front = ins - orig; + tmp = strncpy(tmp, orig, len_front) + len_front; + tmp = strcpy(tmp, with) + len_with; + orig += len_front + len_rep; // move to next "end of rep" + } + strcpy(tmp, orig); + return result; } // Stores the trimmed input string into the given output buffer, which must be // large enough to store the result. If it is too small, the output is // truncated. size_t trimString(char *out, size_t len, const char *str, bool first) { - if (len == 0) - return 0; + if (len == 0) + return 0; - const char *end; - size_t out_size; - bool is_string = false; + const char *end; + size_t out_size; + bool is_string = false; - // Trim leading space - while (strchr("\r\n\t {},", (unsigned char)*str) != NULL) - str++; + // Trim leading space + while (strchr("\r\n\t {},", (unsigned char)*str) != NULL) + str++; - end = str + 1; + end = str + 1; - if ((unsigned char)*str == '"') { - is_string = true; - str++; - while (strchr("\r\n\"", (unsigned char)*end) == NULL) - end++; - } + if ((unsigned char)*str == '"') { + is_string = true; + str++; + while (strchr("\r\n\"", (unsigned char)*end) == NULL) + end++; + } - if (*str == 0) // All spaces? - { - *out = 0; - return 1; - } + if (*str == 0) // All spaces? + { + *out = 0; + return 1; + } - // Trim trailing space - if (first) - while (strchr("\r\n\t {},", (unsigned char)*end) == NULL) - end++; - else { - end = str + strlen(str) - 1; - while (end > str && strchr("\r\n\t {},", (unsigned char)*end) != NULL) - end--; - end++; - } + // Trim trailing space + if (first) + while (strchr("\r\n\t {},", (unsigned char)*end) == NULL) + end++; + else { + end = str + strlen(str) - 1; + while (end > str && strchr("\r\n\t {},", (unsigned char)*end) != NULL) + end--; + end++; + } - if (is_string && (unsigned char)*(end - 1) == '"') - end--; + if (is_string && (unsigned char)*(end - 1) == '"') + end--; - // Set output size to minimum of trimmed string length and buffer size minus - // 1 - out_size = (end - str) < len - 1 ? (end - str) : len - 1; + // Set output size to minimum of trimmed string length and buffer size minus + // 1 + out_size = (end - str) < len - 1 ? (end - str) : len - 1; - // Copy trimmed string and add null terminator - memcpy(out, str, out_size); - out[out_size] = 0; + // Copy trimmed string and add null terminator + memcpy(out, str, out_size); + out[out_size] = 0; - return out_size; + return out_size; } void removeParentheses(char *str_out, const char *str_in) { - char temp[STR_MAX]; - int len = strlen(str_in); - int c = 0; - bool inside = false; - char end_char; - - for (int i = 0; i < len && i < STR_MAX; i++) { - if (!inside && (str_in[i] == '(' || str_in[i] == '[')) { - end_char = str_in[i] == '(' ? ')' : ']'; - inside = true; - continue; - } - else if (inside) { - if (str_in[i] == end_char) - inside = false; - continue; - } - temp[c++] = str_in[i]; - } - - temp[c] = '\0'; - - trimString(str_out, STR_MAX - 1, temp, false); + char temp[STR_MAX]; + int len = strlen(str_in); + int c = 0; + bool inside = false; + char end_char; + + for (int i = 0; i < len && i < STR_MAX; i++) { + if (!inside && (str_in[i] == '(' || str_in[i] == '[')) { + end_char = str_in[i] == '(' ? ')' : ']'; + inside = true; + continue; + } else if (inside) { + if (str_in[i] == end_char) + inside = false; + continue; + } + temp[c++] = str_in[i]; + } + + temp[c] = '\0'; + + trimString(str_out, STR_MAX - 1, temp, false); } void serializeTime(char *dest_str, int nTime) { - if (nTime >= 60) { - int h = nTime / 3600; - int m = (nTime - 3600 * h) / 60; - if (h > 0) { - sprintf(dest_str, "%dh %dm", h, m); - } - else { - sprintf(dest_str, "%dm %ds", m, nTime - 60 * m); - } - } - else { - sprintf(dest_str, "%ds", nTime); - } + if (nTime >= 60) { + int h = nTime / 3600; + int m = (nTime - 3600 * h) / 60; + if (h > 0) { + sprintf(dest_str, "%dh %dm", h, m); + } else { + sprintf(dest_str, "%dm %ds", m, nTime - 60 * m); + } + } else { + sprintf(dest_str, "%ds", nTime); + } } int countChar(const char *str, char ch) { - int i, count = 0; - for (i = 0; i <= strlen(str); i++) { - if (str[i] == ch) { - count++; - } - } - return count; + int i, count = 0; + for (i = 0; i <= strlen(str); i++) { + if (str[i] == ch) { + count++; + } + } + return count; } char *removeExtension(const char *myStr) { - if (myStr == NULL) - return NULL; - char *retStr = (char *)malloc(strlen(myStr) + 1); - char *lastExt; - if (retStr == NULL) - return NULL; - strcpy(retStr, myStr); - if ((lastExt = strrchr(retStr, '.')) != NULL && *(lastExt + 1) != ' ' && *(lastExt + 2) != '\0') - *lastExt = '\0'; - return retStr; + if (myStr == NULL) + return NULL; + char *retStr = (char *)malloc(strlen(myStr) + 1); + char *lastExt; + if (retStr == NULL) + return NULL; + strcpy(retStr, myStr); + if ((lastExt = strrchr(retStr, '.')) != NULL && *(lastExt + 1) != ' ' && *(lastExt + 2) != '\0') + *lastExt = '\0'; + return retStr; } const char *baseName(const char *filename) { - char *p = strrchr(filename, '/'); - return p ? p + 1 : (char *)filename; + char *p = strrchr(filename, '/'); + return p ? p + 1 : (char *)filename; } -void folderPath(const char *path, char *result) { - char pathCopy[256]; - strcpy(pathCopy, path); - - char *lastSlash = strrchr(pathCopy, '/'); // Find the last slash - if (lastSlash != NULL) { - *lastSlash = '\0'; // Cut off the filename - strcpy(result, pathCopy); // Copy the remaining path - } else { - strcpy(result, ""); // No folder found - } +void folderPath(const char *path, char *result) +{ + char pathCopy[256]; + strcpy(pathCopy, path); + + char *lastSlash = strrchr(pathCopy, '/'); // Find the last slash + if (lastSlash != NULL) { + *lastSlash = '\0'; // Cut off the filename + strcpy(result, pathCopy); // Copy the remaining path + } else { + strcpy(result, ""); // No folder found + } } void cleanName(char *name_out, const char *file_name) { - char *name_without_ext = removeExtension(file_name); - char *no_underscores = replaceString2(name_without_ext, "_", " "); - char *dot_ptr = strstr(no_underscores, "."); - if (dot_ptr != NULL) { - char *s = no_underscores; - while (isdigit(*s) && s < dot_ptr) - s++; - if (s != dot_ptr) - dot_ptr = no_underscores; - else { - dot_ptr++; - if (dot_ptr[0] == ' ') - dot_ptr++; - } - } - else { - dot_ptr = no_underscores; - } - removeParentheses(name_out, dot_ptr); - free(name_without_ext); - free(no_underscores); + char *name_without_ext = removeExtension(file_name); + char *no_underscores = replaceString2(name_without_ext, "_", " "); + char *dot_ptr = strstr(no_underscores, "."); + if (dot_ptr != NULL) { + char *s = no_underscores; + while (isdigit(*s) && s < dot_ptr) + s++; + if (s != dot_ptr) + dot_ptr = no_underscores; + else { + dot_ptr++; + if (dot_ptr[0] == ' ') + dot_ptr++; + } + } else { + dot_ptr = no_underscores; + } + removeParentheses(name_out, dot_ptr); + free(name_without_ext); + free(no_underscores); } bool pathRelativeTo(char *path_out, const char *dir_from, const char *file_to) { - path_out[0] = '\0'; + path_out[0] = '\0'; - char abs_from[MAX_PATH]; - char abs_to[MAX_PATH]; - if (realpath(dir_from, abs_from) == NULL || realpath(file_to, abs_to) == NULL) { - return false; - } + char abs_from[MAX_PATH]; + char abs_to[MAX_PATH]; + if (realpath(dir_from, abs_from) == NULL || realpath(file_to, abs_to) == NULL) { + return false; + } - char *p1 = abs_from; - char *p2 = abs_to; - while (*p1 && (*p1 == *p2)) { - ++p1, ++p2; - } + char *p1 = abs_from; + char *p2 = abs_to; + while (*p1 && (*p1 == *p2)) { + ++p1, ++p2; + } - if (*p2 == '/') { - ++p2; - } + if (*p2 == '/') { + ++p2; + } - if (strlen(p1) > 0) { - int num_parens = countChar(p1, '/') + 1; - for (int i = 0; i < num_parens; i++) { - strcat(path_out, "../"); - } - } - strcat(path_out, p2); + if (strlen(p1) > 0) { + int num_parens = countChar(p1, '/') + 1; + for (int i = 0; i < num_parens; i++) { + strcat(path_out, "../"); + } + } + strcat(path_out, p2); - return true; + return true; } -void getDisplayName(const char* in_name, char* out_name) { - char* tmp; +void getDisplayName(const char *in_name, char *out_name) +{ + char *tmp; char work_name[256]; strcpy(work_name, in_name); strcpy(out_name, in_name); - + if (suffixMatch("/" PLATFORM, work_name)) { // hide platform from Tools path... tmp = strrchr(work_name, '/'); tmp[0] = '\0'; } - + // extract just the filename if necessary tmp = strrchr(work_name, '/'); - if (tmp) strcpy(out_name, tmp+1); - + if (tmp) + strcpy(out_name, tmp + 1); + // remove extension(s), eg. .p8.png - while ((tmp = strrchr(out_name, '.'))!=NULL) { + while ((tmp = strrchr(out_name, '.')) != NULL) { int len = strlen(tmp); - if (len>2 && len<=5) tmp[0] = '\0'; // 1-4 letter extension plus dot (was 1-3, extended for .doom files) - else break; + if (len > 2 && len <= 5) + tmp[0] = '\0'; // 1-4 letter extension plus dot (was 1-3, extended for .doom files) + else + break; } - + // remove trailing parens (round and square) strcpy(work_name, out_name); - while ((tmp=strrchr(out_name, '('))!=NULL || (tmp=strrchr(out_name, '['))!=NULL) { - if (tmp==out_name) break; + while ((tmp = strrchr(out_name, '(')) != NULL || (tmp = strrchr(out_name, '[')) != NULL) { + if (tmp == out_name) + break; tmp[0] = '\0'; tmp = out_name; } - + // make sure we haven't nuked the entire name - if (out_name[0]=='\0') strcpy(out_name, work_name); - + if (out_name[0] == '\0') + strcpy(out_name, work_name); + // remove trailing whitespace tmp = out_name + strlen(out_name) - 1; - while(tmp>out_name && isspace((unsigned char)*tmp)) tmp--; - tmp[1] = '\0'; + while (tmp > out_name && isspace((unsigned char)*tmp)) + tmp--; + tmp[1] = '\0'; } -void getEmuName(const char* in_name, char* out_name) { // NOTE: both char arrays need to be MAX_PATH length! - char* tmp; +void getEmuName(const char *in_name, char *out_name) +{ // NOTE: both char arrays need to be MAX_PATH length! + char *tmp; strcpy(out_name, in_name); tmp = out_name; - + // printf("--------\n in_name: %s\n",in_name); fflush(stdout); - + // extract just the Roms folder name if necessary if (prefixMatch(ROMS_PATH, tmp)) { tmp += strlen(ROMS_PATH) + 1; - char* tmp2 = strchr(tmp, '/'); - if (tmp2) tmp2[0] = '\0'; + char *tmp2 = strchr(tmp, '/'); + if (tmp2) + tmp2[0] = '\0'; // printf(" tmp1: %s\n", tmp); strcpy(out_name, tmp); tmp = out_name; @@ -368,91 +384,104 @@ void getEmuName(const char* in_name, char* out_name) { // NOTE: both char arrays tmp += 1; // printf(" tmp2: %s\n", tmp); strcpy(out_name, tmp); - tmp = strchr(out_name,')'); + tmp = strchr(out_name, ')'); tmp[0] = '\0'; } - + // printf(" out_name: %s\n", out_name); fflush(stdout); } -void getEmuPath(char* emu_name, char* pak_path) { +void getEmuPath(char *emu_name, char *pak_path) +{ sprintf(pak_path, "%s/Emus/%s/%s.pak/launch.sh", SDCARD_PATH, PLATFORM, emu_name); - if (exists(pak_path)) return; + if (exists(pak_path)) + return; sprintf(pak_path, "%s/Emus/%s.pak/launch.sh", PAKS_PATH, emu_name); } -void normalizeNewline(char* line) { +void normalizeNewline(char *line) +{ int len = strlen(line); - if (len>1 && line[len-1]=='\n' && line[len-2]=='\r') { // windows! - line[len-2] = '\n'; - line[len-1] = '\0'; + if (len > 1 && line[len - 1] == '\n' && line[len - 2] == '\r') { // windows! + line[len - 2] = '\n'; + line[len - 1] = '\0'; } } -void trimTrailingNewlines(char* line) { +void trimTrailingNewlines(char *line) +{ int len = strlen(line); - while (len>0 && line[len-1]=='\n') { - line[len-1] = '\0'; // trim newline + while (len > 0 && line[len - 1] == '\n') { + line[len - 1] = '\0'; // trim newline len -= 1; } } -void trimSortingMeta(char** str) { // eg. `001) ` +void trimSortingMeta(char **str) +{ // eg. `001) ` // TODO: this code is suss - char* safe = *str; - while(isdigit(**str)) *str += 1; // ignore leading numbers + char *safe = *str; + while (isdigit(**str)) + *str += 1; // ignore leading numbers - if (*str[0]==')') { // then match a closing parenthesis + if (*str[0] == ')') { // then match a closing parenthesis *str += 1; - } - else { // or bail, restoring the string to its original value + } else { // or bail, restoring the string to its original value *str = safe; return; } - - while(isblank(**str)) *str += 1; // ignore leading space + + while (isblank(**str)) + *str += 1; // ignore leading space } /////////////////////////////////////// -int exists(char* path) { - return access(path, F_OK)==0; +int exists(char *path) +{ + return access(path, F_OK) == 0; } -void touch(char* path) { - close(open(path, O_RDWR|O_CREAT, 0777)); +void touch(char *path) +{ + close(open(path, O_RDWR | O_CREAT, 0777)); } -int toggle(char *path) { - if (access(path, F_OK) == 0) { - unlink(path); - return 0; - } else { - touch(path); - return 1; - } +int toggle(char *path) +{ + if (access(path, F_OK) == 0) { + unlink(path); + return 0; + } else { + touch(path); + return 1; + } } -void putFile(char* path, char* contents) { - FILE* file = fopen(path, "w"); +void putFile(char *path, char *contents) +{ + FILE *file = fopen(path, "w"); if (file) { fputs(contents, file); fclose(file); } } -void getFile(char* path, char* buffer, size_t buffer_size) { +void getFile(char *path, char *buffer, size_t buffer_size) +{ FILE *file = fopen(path, "r"); if (file) { fseek(file, 0L, SEEK_END); size_t size = ftell(file); - if (size>buffer_size-1) size = buffer_size - 1; + if (size > buffer_size - 1) + size = buffer_size - 1; rewind(file); fread(buffer, sizeof(char), size, file); fclose(file); buffer[size] = '\0'; } } -char* allocFile(char* path) { // caller must free! - char* contents = NULL; +char *allocFile(char *path) +{ // caller must free! + char *contents = NULL; FILE *file = fopen(path, "r"); if (file) { fseek(file, 0L, SEEK_END); size_t size = ftell(file); - contents = calloc(size+1, sizeof(char)); + contents = calloc(size + 1, sizeof(char)); fseek(file, 0L, SEEK_SET); fread(contents, sizeof(char), size, file); fclose(file); @@ -460,58 +489,61 @@ char* allocFile(char* path) { // caller must free! } return contents; } -int getInt(char* path) { +int getInt(char *path) +{ int i = 0; - if(path == NULL) - return i; - + if (path == NULL) + return i; + FILE *file = fopen(path, "r"); - if (file!=NULL) { + if (file != NULL) { int res = fscanf(file, "%i", &i); fclose(file); - if(res != 1) - i = 0; // failed to parse int + if (res != 1) + i = 0; // failed to parse int } return i; } -void putInt(char* path, int value) { +void putInt(char *path, int value) +{ char buffer[8]; sprintf(buffer, "%d", value); putFile(path, buffer); } -uint64_t getMicroseconds(void) { - uint64_t ret; - struct timeval tv; +uint64_t getMicroseconds(void) +{ + uint64_t ret; + struct timeval tv; - gettimeofday(&tv, NULL); + gettimeofday(&tv, NULL); - ret = (uint64_t)tv.tv_sec * 1000000; - ret += (uint64_t)tv.tv_usec; + ret = (uint64_t)tv.tv_sec * 1000000; + ret += (uint64_t)tv.tv_usec; - return ret; + return ret; } -#define max(a,b) \ -({ \ - __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a > _b ? _a : _b; \ -}) +#define max(a, b) \ + ({ \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + _a > _b ? _a : _b; \ + }) -#define min(a,b) \ -({ \ - __typeof__ (a) _a = (a); \ - __typeof__ (b) _b = (b); \ - _a < _b ? _a : _b; \ -}) +#define min(a, b) \ + ({ \ + __typeof__(a) _a = (a); \ + __typeof__(b) _b = (b); \ + _a < _b ? _a : _b; \ + }) int clamp(int x, int lower, int upper) { - return min(upper, max(x, lower)); + return min(upper, max(x, lower)); } double clampd(double x, double lower, double upper) { - return min(upper, max(x, lower)); + return min(upper, max(x, lower)); } \ No newline at end of file diff --git a/workspace/all/common/utils.h b/workspace/all/common/utils.h index b7dbd8ff8..b93ce0a04 100644 --- a/workspace/all/common/utils.h +++ b/workspace/all/common/utils.h @@ -5,11 +5,11 @@ #include #include -int prefixMatch(char* pre, const char* str); -int suffixMatch(char* suf,const char* str); -int exactMatch(const char* str1, const char* str2); -int containsString(char* haystack, char* needle); -int hide(char* file_name); +int prefixMatch(char *pre, const char *str); +int suffixMatch(char *suf, const char *str); +int exactMatch(const char *str1, const char *str2); +int containsString(char *haystack, char *needle); +int hide(char *file_name); char *splitString(char *str, const char *delim); char *replaceString2(const char *orig, char *rep, char *with); @@ -25,22 +25,22 @@ void folderPath(const char *filePath, char *folder_path); void cleanName(char *name_out, const char *file_name); bool pathRelativeTo(char *path_out, const char *dir_from, const char *file_to); -void getDisplayName(const char* in_name, char* out_name); -void getEmuName(const char* in_name, char* out_name); -void getEmuPath(char* emu_name, char* pak_path); +void getDisplayName(const char *in_name, char *out_name); +void getEmuName(const char *in_name, char *out_name); +void getEmuPath(char *emu_name, char *pak_path); -void normalizeNewline(char* line); -void trimTrailingNewlines(char* line); -void trimSortingMeta(char** str); +void normalizeNewline(char *line); +void trimTrailingNewlines(char *line); +void trimSortingMeta(char **str); -int exists(char* path); -void touch(char* path); +int exists(char *path); +void touch(char *path); int toggle(char *path); // creates or removes file void putFile(char *path, char *contents); -char* allocFile(char* path); // caller must free -void getFile(char* path, char* buffer, size_t buffer_size); -void putInt(char* path, int value); -int getInt(char* path); +char *allocFile(char *path); // caller must free +void getFile(char *path, char *buffer, size_t buffer_size); +void putInt(char *path, int value); +int getInt(char *path); uint64_t getMicroseconds(void); diff --git a/workspace/all/gametime/gametime.c b/workspace/all/gametime/gametime.c index f3913a060..4be1ba95f 100644 --- a/workspace/all/gametime/gametime.c +++ b/workspace/all/gametime/gametime.c @@ -1,4 +1,5 @@ -// heavily modified from the Onion original: https://github.com/OnionUI/Onion/blob/main/src/playActivity/playActivityUI.c +// heavily modified from the Onion original: +// https://github.com/OnionUI/Onion/blob/main/src/playActivity/playActivityUI.c #include #include #include @@ -12,33 +13,32 @@ #include #include -struct ListLayout -{ - int list_display_size_x; - int list_display_size_y; - int list_display_start_x; - int list_display_start_y; - SDL_Rect list_display_rect; +struct ListLayout { + int list_display_size_x; + int list_display_size_y; + int list_display_start_x; + int list_display_start_y; + SDL_Rect list_display_rect; - int sub_title_x; - int sub_title_y; + int sub_title_x; + int sub_title_y; - int items_per_page; - int num_pages; + int items_per_page; + int num_pages; } layout = {0}; static bool quit = false; static void sigHandler(int sig) { - switch (sig) { - case SIGINT: - case SIGTERM: - quit = true; - break; - default: - break; - } + switch (sig) { + case SIGINT: + case SIGTERM: + quit = true; + break; + default: + break; + } } #define BIG_PILL_SIZE 48 @@ -65,396 +65,381 @@ static inline SDL_Color colorFromUint(uint32_t colour) int _renderText(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rect, bool right_align) { - int text_width = 0; - SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, text, color); - if (textSurface != NULL) { - text_width = textSurface->w; - if (right_align) - SDL_BlitSurface(textSurface, NULL, screen, &(SDL_Rect){rect->w - textSurface->w, rect->y, rect->w, rect->h}); - else - SDL_BlitSurface(textSurface, NULL, screen, rect); - SDL_FreeSurface(textSurface); - } - return text_width; + int text_width = 0; + SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, text, color); + if (textSurface != NULL) { + text_width = textSurface->w; + if (right_align) + SDL_BlitSurface(textSurface, NULL, screen, + &(SDL_Rect){rect->w - textSurface->w, rect->y, rect->w, rect->h}); + else + SDL_BlitSurface(textSurface, NULL, screen, rect); + SDL_FreeSurface(textSurface); + } + return text_width; } int renderText(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rect) { - return _renderText(text, font, color, rect, false); + return _renderText(text, font, color, rect, false); } int renderTextAlignRight(const char *text, TTF_Font *font, SDL_Color color, SDL_Rect *rect) { - return _renderText(text, font, color, rect, true); + return _renderText(text, font, color, rect, true); } // Set a pixel color on the surface -void _setPixel(SDL_Surface *surface, int x, int y, Uint32 color) { - if (x < 0 || x >= surface->w || y < 0 || y >= surface->h) { - return; // Out of bounds check - } - - // Lock surface if needed - SDL_LockSurface(surface); - - Uint8 *pixelPtr = (Uint8 *)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel; - - switch (surface->format->BytesPerPixel) { - case 1: - *pixelPtr = color; - break; - case 2: - *(Uint16 *)pixelPtr = color; - break; - case 3: - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { - pixelPtr[0] = (color >> 16) & 0xFF; - pixelPtr[1] = (color >> 8) & 0xFF; - pixelPtr[2] = color & 0xFF; - } else { - pixelPtr[0] = color & 0xFF; - pixelPtr[1] = (color >> 8) & 0xFF; - pixelPtr[2] = (color >> 16) & 0xFF; - } - break; - case 4: - *(Uint32 *)pixelPtr = color; - break; - } - - SDL_UnlockSurface(surface); +void _setPixel(SDL_Surface *surface, int x, int y, Uint32 color) +{ + if (x < 0 || x >= surface->w || y < 0 || y >= surface->h) { + return; // Out of bounds check + } + + // Lock surface if needed + SDL_LockSurface(surface); + + Uint8 *pixelPtr = (Uint8 *)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel; + + switch (surface->format->BytesPerPixel) { + case 1: + *pixelPtr = color; + break; + case 2: + *(Uint16 *)pixelPtr = color; + break; + case 3: + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { + pixelPtr[0] = (color >> 16) & 0xFF; + pixelPtr[1] = (color >> 8) & 0xFF; + pixelPtr[2] = color & 0xFF; + } else { + pixelPtr[0] = color & 0xFF; + pixelPtr[1] = (color >> 8) & 0xFF; + pixelPtr[2] = (color >> 16) & 0xFF; + } + break; + case 4: + *(Uint32 *)pixelPtr = color; + break; + } + + SDL_UnlockSurface(surface); } // Draw a filled circle -void _drawFilledCircle(SDL_Surface *surface, int cx, int cy, int radius, Uint32 color) { - for (int y = -radius; y <= radius; y++) { - for (int x = -radius; x <= radius; x++) { - if (x * x + y * y <= radius * radius) { - _setPixel(surface, cx + x, cy + y, color); - } - } - } +void _drawFilledCircle(SDL_Surface *surface, int cx, int cy, int radius, Uint32 color) +{ + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + if (x * x + y * y <= radius * radius) { + _setPixel(surface, cx + x, cy + y, color); + } + } + } } // Draw a filled rounded rectangle -void renderRoundedRectangle(SDL_Rect rect, Uint32 color, int radius) { - // Fill the center and straight edges - SDL_Rect fillRect = {rect.x + radius, rect.y, rect.w - 2 * radius, rect.h}; - SDL_FillRect(screen, &fillRect, color); - - fillRect.x = rect.x; - fillRect.y = rect.y + radius; - fillRect.w = rect.w; - fillRect.h = rect.h - 2 * radius; - SDL_FillRect(screen, &fillRect, color); - - // Draw the corner circles - _drawFilledCircle(screen, rect.x + radius, rect.y + radius, radius, color); // Top-left - _drawFilledCircle(screen, rect.x + rect.w - radius - 1, rect.y + radius, radius, color); // Top-right - _drawFilledCircle(screen, rect.x + radius, rect.y + rect.h - radius - 1, radius, color); // Bottom-left - _drawFilledCircle(screen, rect.x + rect.w - radius - 1, rect.y + rect.h - radius - 1, radius, color); // Bottom-right +void renderRoundedRectangle(SDL_Rect rect, Uint32 color, int radius) +{ + // Fill the center and straight edges + SDL_Rect fillRect = {rect.x + radius, rect.y, rect.w - 2 * radius, rect.h}; + SDL_FillRect(screen, &fillRect, color); + + fillRect.x = rect.x; + fillRect.y = rect.y + radius; + fillRect.w = rect.w; + fillRect.h = rect.h - 2 * radius; + SDL_FillRect(screen, &fillRect, color); + + // Draw the corner circles + _drawFilledCircle(screen, rect.x + radius, rect.y + radius, radius, color); // Top-left + _drawFilledCircle(screen, rect.x + rect.w - radius - 1, rect.y + radius, radius, color); // Top-right + _drawFilledCircle(screen, rect.x + radius, rect.y + rect.h - radius - 1, radius, color); // Bottom-left + _drawFilledCircle(screen, rect.x + rect.w - radius - 1, rect.y + rect.h - radius - 1, radius, + color); // Bottom-right } SDL_Surface *loadRomImage(char *image_path) { - if(!exists(image_path)) - return NULL; - - SDL_Surface *img = IMG_Load(image_path); - if(!img) - return NULL; - - if(img->format->format != SDL_PIXELFORMAT_RGBA32) { - SDL_Surface *optimized = SDL_ConvertSurfaceFormat(img, SDL_PIXELFORMAT_RGBA32, 0); - SDL_FreeSurface(img); - img = optimized; - } - - SDL_PixelFormat *ft = img->format; - SDL_Surface *dst = SDL_CreateRGBSurface(0, SCALE1(IMG_MAX_WIDTH), SCALE1(IMG_MAX_HEIGHT), ft->BitsPerPixel, ft->Rmask, ft->Gmask, ft->Bmask, ft->Amask); - SDL_Rect imgRect = GFX_blitScaled(GFX_SCALE_FILL, img, dst); - GFX_ApplyRoundedCorners(dst, &imgRect, SCALE1(18)); - SDL_FreeSurface(img); - - return dst; + if (!exists(image_path)) + return NULL; + + SDL_Surface *img = IMG_Load(image_path); + if (!img) + return NULL; + + if (img->format->format != SDL_PIXELFORMAT_RGBA32) { + SDL_Surface *optimized = SDL_ConvertSurfaceFormat(img, SDL_PIXELFORMAT_RGBA32, 0); + SDL_FreeSurface(img); + img = optimized; + } + + SDL_PixelFormat *ft = img->format; + SDL_Surface *dst = SDL_CreateRGBSurface(0, SCALE1(IMG_MAX_WIDTH), SCALE1(IMG_MAX_HEIGHT), ft->BitsPerPixel, + ft->Rmask, ft->Gmask, ft->Bmask, ft->Amask); + SDL_Rect imgRect = GFX_blitScaled(GFX_SCALE_FILL, img, dst); + GFX_ApplyRoundedCorners(dst, &imgRect, SCALE1(18)); + SDL_FreeSurface(img); + + return dst; } void preloadRomImages() { - // load all rom images into SDL_Surfaces - romImages = malloc(sizeof(SDL_Surface *) * play_activities->count); - for (int i = 0; i < play_activities->count; i++) { - PlayActivity *entry = play_activities->play_activity[i]; - ROM *rom = entry->rom; - romImages[i] = loadRomImage(rom->image_path); - } + // load all rom images into SDL_Surfaces + romImages = malloc(sizeof(SDL_Surface *) * play_activities->count); + for (int i = 0; i < play_activities->count; i++) { + PlayActivity *entry = play_activities->play_activity[i]; + ROM *rom = entry->rom; + romImages[i] = loadRomImage(rom->image_path); + } } void freeRomImages() { - for (int i = 0; i < play_activities->count; i++) { - SDL_FreeSurface(romImages[i]); - } - free(romImages); + for (int i = 0; i < play_activities->count; i++) { + SDL_FreeSurface(romImages[i]); + } + free(romImages); } void renderList(int count, int start, int end, int selected) { - char num_str[12]; - char rom_name[255]; - char total[25]; - char average[25]; - char plays[25]; - - int num_width = 0; - - const int elemHeight = SCALE1(BIG_PILL_SIZE); - const int thumbMargin = SCALE1(IMG_MARGIN); - const int textHeight = (elemHeight - thumbMargin) / 2; - - int selected_row = selected - start; - for (int index=start,row=0; indexplay_activity[index]; - ROM *rom = entry->rom; - - renderRoundedRectangle((SDL_Rect){ - layout.list_display_start_x, - layout.list_display_start_y + row * elemHeight, - layout.list_display_size_x, - elemHeight - }, isSelected ? RGB_WHITE : RGB_BLACK, SCALE1(24)); - - SDL_Surface *romImage = romImages[index]; - if (romImage) { - SDL_Rect rectRomImage = { - layout.list_display_start_x + num_width + thumbMargin / 2 + (SCALE1(IMG_MAX_WIDTH) - romImage->w) / 2, - layout.list_display_start_y + elemHeight * row + thumbMargin / 2, - SCALE1(IMG_MAX_WIDTH), - SCALE1(IMG_MAX_HEIGHT) - }; - SDL_BlitSurface(romImage, NULL, screen, &rectRomImage); - } - else { - SDL_Rect rectRomImage = { - layout.list_display_start_x + num_width + thumbMargin / 2, - layout.list_display_start_y + elemHeight * row + thumbMargin / 2, - SCALE1(IMG_MAX_WIDTH), - SCALE1(IMG_MAX_HEIGHT) - }; - - renderRoundedRectangle(rectRomImage, RGB_DARK_GRAY, SCALE1(18)); - - // TODO: no getter exposed for this right now - //SDL_Rect rect = asset_rects[ASSET_GAMEPAD]; - SDL_Rect rect = (SDL_Rect){SCALE4(92,51,18,10)}; - int x = rectRomImage.x; - int y = rectRomImage.y; - x += (SCALE1(IMG_MAX_WIDTH) - rect.w) / 2; - y += (SCALE1(IMG_MAX_HEIGHT) - rect.h) / 2; - - GFX_blitAssetColor(ASSET_GAMEPAD, NULL, screen, &(SDL_Rect){x,y}, THEME_COLOR1_255); - } - - cleanName(rom_name, rom->name); - SDL_Color textColor = COLOR_WHITE; - if(isSelected) { - //textColor = colorFromUint(THEME_COLOR1); - textColor = COLOR_BLACK; - } - renderText(rom_name, font.medium, textColor, &(SDL_Rect){ - layout.list_display_start_x + num_width + thumbMargin + SCALE1(IMG_MAX_WIDTH), - layout.list_display_start_y + thumbMargin / 2 + elemHeight * row, - layout.list_display_size_x, - textHeight}); - - serializeTime(total, entry->play_time_total); - serializeTime(average, entry->play_time_average); - snprintf(plays, 24, "%d", entry->play_count); - - const char *details[] = {"TOTAL ", total, " AVERAGE ", average, " # PLAYS ", plays}; - SDL_Rect detailsRect = { - layout.list_display_start_x + num_width + thumbMargin + SCALE1(IMG_MAX_WIDTH), - layout.list_display_start_y + thumbMargin + textHeight + elemHeight * row, - layout.list_display_size_x, - textHeight - }; - for (int i = 0; i < 6; i++) { - SDL_Color detailCol = i % 2 == 0 ? COLOR_DARK_TEXT : colorFromUint(THEME_COLOR2_255); - //SDL_Color detailCol = colorFromUint(i % 2 == 0 ? THEME_COLOR3_255 : THEME_COLOR2_255); - //SDL_Color detailCol = i % 2 == 0 ? COLOR_DARK_TEXT : COLOR_LIGHT_TEXT; - detailsRect.x += renderText(details[i], font.small, detailCol, &detailsRect); - } - } - - if (count>layout.items_per_page) { - #define SCROLL_WIDTH 24 - #define SCROLL_HEIGHT 4 - int ox = (screen->w - SCALE1(SCROLL_WIDTH)) / 2; - int oy = SCALE1((PILL_SIZE - SCROLL_HEIGHT) / 2); - if (start>0) - GFX_blitAsset(ASSET_SCROLL_UP, NULL, screen, &(SDL_Rect){ox, SCALE1(PADDING + PILL_SIZE)}); - if (endh - SCALE1(PADDING + PILL_SIZE + BUTTON_SIZE) + oy}); - } + char num_str[12]; + char rom_name[255]; + char total[25]; + char average[25]; + char plays[25]; + + int num_width = 0; + + const int elemHeight = SCALE1(BIG_PILL_SIZE); + const int thumbMargin = SCALE1(IMG_MARGIN); + const int textHeight = (elemHeight - thumbMargin) / 2; + + int selected_row = selected - start; + for (int index = start, row = 0; index < end; index++, row++) { + bool isSelected = selected_row == row; + + PlayActivity *entry = play_activities->play_activity[index]; + ROM *rom = entry->rom; + + renderRoundedRectangle((SDL_Rect){layout.list_display_start_x, layout.list_display_start_y + row * elemHeight, + layout.list_display_size_x, elemHeight}, + isSelected ? RGB_WHITE : RGB_BLACK, SCALE1(24)); + + SDL_Surface *romImage = romImages[index]; + if (romImage) { + SDL_Rect rectRomImage = {layout.list_display_start_x + num_width + thumbMargin / 2 + + (SCALE1(IMG_MAX_WIDTH) - romImage->w) / 2, + layout.list_display_start_y + elemHeight * row + thumbMargin / 2, + SCALE1(IMG_MAX_WIDTH), SCALE1(IMG_MAX_HEIGHT)}; + SDL_BlitSurface(romImage, NULL, screen, &rectRomImage); + } else { + SDL_Rect rectRomImage = {layout.list_display_start_x + num_width + thumbMargin / 2, + layout.list_display_start_y + elemHeight * row + thumbMargin / 2, + SCALE1(IMG_MAX_WIDTH), SCALE1(IMG_MAX_HEIGHT)}; + + renderRoundedRectangle(rectRomImage, RGB_DARK_GRAY, SCALE1(18)); + + // TODO: no getter exposed for this right now + // SDL_Rect rect = asset_rects[ASSET_GAMEPAD]; + SDL_Rect rect = (SDL_Rect){SCALE4(92, 51, 18, 10)}; + int x = rectRomImage.x; + int y = rectRomImage.y; + x += (SCALE1(IMG_MAX_WIDTH) - rect.w) / 2; + y += (SCALE1(IMG_MAX_HEIGHT) - rect.h) / 2; + + GFX_blitAssetColor(ASSET_GAMEPAD, NULL, screen, &(SDL_Rect){x, y}, THEME_COLOR1_255); + } + + cleanName(rom_name, rom->name); + SDL_Color textColor = COLOR_WHITE; + if (isSelected) { + // textColor = colorFromUint(THEME_COLOR1); + textColor = COLOR_BLACK; + } + renderText(rom_name, font.medium, textColor, + &(SDL_Rect){layout.list_display_start_x + num_width + thumbMargin + SCALE1(IMG_MAX_WIDTH), + layout.list_display_start_y + thumbMargin / 2 + elemHeight * row, + layout.list_display_size_x, textHeight}); + + serializeTime(total, entry->play_time_total); + serializeTime(average, entry->play_time_average); + snprintf(plays, 24, "%d", entry->play_count); + + const char *details[] = {"TOTAL ", total, " AVERAGE ", average, " # PLAYS ", plays}; + SDL_Rect detailsRect = {layout.list_display_start_x + num_width + thumbMargin + SCALE1(IMG_MAX_WIDTH), + layout.list_display_start_y + thumbMargin + textHeight + elemHeight * row, + layout.list_display_size_x, textHeight}; + for (int i = 0; i < 6; i++) { + SDL_Color detailCol = i % 2 == 0 ? COLOR_DARK_TEXT : colorFromUint(THEME_COLOR2_255); + // SDL_Color detailCol = colorFromUint(i % 2 == 0 ? THEME_COLOR3_255 : THEME_COLOR2_255); + // SDL_Color detailCol = i % 2 == 0 ? COLOR_DARK_TEXT : COLOR_LIGHT_TEXT; + detailsRect.x += renderText(details[i], font.small, detailCol, &detailsRect); + } + } + + if (count > layout.items_per_page) { +#define SCROLL_WIDTH 24 +#define SCROLL_HEIGHT 4 + int ox = (screen->w - SCALE1(SCROLL_WIDTH)) / 2; + int oy = SCALE1((PILL_SIZE - SCROLL_HEIGHT) / 2); + if (start > 0) + GFX_blitAsset(ASSET_SCROLL_UP, NULL, screen, &(SDL_Rect){ox, SCALE1(PADDING + PILL_SIZE)}); + if (end < count) + GFX_blitAsset(ASSET_SCROLL_DOWN, NULL, screen, + &(SDL_Rect){ox, screen->h - SCALE1(PADDING + PILL_SIZE + BUTTON_SIZE) + oy}); + } } void initLayout() { - // unscaled - int hw = screen->w; - int hh = screen->h; - - // the title. just leave the default padding all around - layout.sub_title_x = SCALE1(PADDING); - layout.sub_title_y = SCALE1(PADDING); - - // the main list. - // x: start inside the default padding, and align with the title pill. - // y: default padding, below the title pill and some additional padding to leave some breathing room (BUTTON_MARGIN). - layout.list_display_start_x = SCALE1(PADDING); - layout.list_display_start_y = SCALE1(PADDING + PILL_SIZE + BUTTON_MARGIN); - // x: stretch whole width inside default padding + extra margin (see above). - // y: stretch whole height below list_display_start_y, leaving room at the bottom for padding and button hints. - layout.list_display_size_x = hw - SCALE1(PADDING * 2); - layout.list_display_size_y = hh - SCALE1(PADDING * 2 + PILL_SIZE * 2 + BUTTON_MARGIN * 2); - - layout.list_display_rect.x = layout.list_display_start_x, - layout.list_display_rect.y = layout.list_display_start_y, - layout.list_display_rect.w = layout.list_display_size_x, - layout.list_display_rect.h = layout.list_display_size_y; - - layout.items_per_page = layout.list_display_size_y / SCALE1(BIG_PILL_SIZE); - layout.num_pages = (int)ceil((double)play_activities->count / (double)layout.items_per_page); + // unscaled + int hw = screen->w; + int hh = screen->h; + + // the title. just leave the default padding all around + layout.sub_title_x = SCALE1(PADDING); + layout.sub_title_y = SCALE1(PADDING); + + // the main list. + // x: start inside the default padding, and align with the title pill. + // y: default padding, below the title pill and some additional padding to leave some breathing room + // (BUTTON_MARGIN). + layout.list_display_start_x = SCALE1(PADDING); + layout.list_display_start_y = SCALE1(PADDING + PILL_SIZE + BUTTON_MARGIN); + // x: stretch whole width inside default padding + extra margin (see above). + // y: stretch whole height below list_display_start_y, leaving room at the bottom for padding and button hints. + layout.list_display_size_x = hw - SCALE1(PADDING * 2); + layout.list_display_size_y = hh - SCALE1(PADDING * 2 + PILL_SIZE * 2 + BUTTON_MARGIN * 2); + + layout.list_display_rect.x = layout.list_display_start_x, layout.list_display_rect.y = layout.list_display_start_y, + layout.list_display_rect.w = layout.list_display_size_x, layout.list_display_rect.h = layout.list_display_size_y; + + layout.items_per_page = layout.list_display_size_y / SCALE1(BIG_PILL_SIZE); + layout.num_pages = (int)ceil((double)play_activities->count / (double)layout.items_per_page); } int main(int argc, char *argv[]) { - InitSettings(); - - PWR_setCPUSpeed(CPU_SPEED_MENU); - - screen = GFX_init(MODE_MAIN); - PAD_init(); - PWR_init(); - - signal(SIGINT, sigHandler); - signal(SIGTERM, sigHandler); - - play_activities = play_activity_find_all(); - LOG_debug("found %d roms\n", play_activities->count); - - initLayout(); - preloadRomImages(); - int count = play_activities->count; - int selected = 0; - int start = 0; - int end = MIN(count, layout.items_per_page); - int visible_rows = end; - - int dirty = 1; - int show_setting = 0; - while (!quit) - { - uint32_t frame_start = SDL_GetTicks(); - - PAD_poll(); - - // This might be too harsh, but ignore all combos with MENU (most likely a shortcut for someone else) - if (PAD_justPressed(BTN_MENU)) - { - // ? - } - else { - if (PAD_justRepeated(BTN_UP)) - { - selected -= 1; - if (selected<0) { - selected = count - 1; - start = MAX(0,count - layout.items_per_page); - end = count; - } - else if (selected=count) { - selected = 0; - start = 0; - end = visible_rows; - } - else if (selected>=end) { - start += 1; - end += 1; - } - dirty = 1; - } - else if (PAD_justPressed(BTN_B)) - { - quit = 1; - } - } - - PWR_update(&dirty, &show_setting, NULL, NULL); - - if (dirty) { - GFX_clear(screen); - - // title pill - { - int max_width = screen->w - SCALE1(PADDING * 2); - if(screen->w >= SCALE1(320)) { - int ow = GFX_blitHardwareGroup(screen, show_setting); - max_width = screen->w - SCALE1(PADDING * 2) - ow; - } - - int play_time_total = play_activities->play_time_total; - char play_time_total_formatted[255]; - serializeTime(play_time_total_formatted, play_time_total); - char display_name[256]; - sprintf(display_name, "Time spent having fun: %s", play_time_total_formatted); - - char title[256]; - int text_width = GFX_truncateText(font.large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); - max_width = MIN(max_width, text_width); - - SDL_Surface *text; - text = TTF_RenderUTF8_Blended(font.large, title, COLOR_WHITE); - GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); - SDL_FreeSurface(text); - } - - renderList(count, start, end, selected); - - if (show_setting) - GFX_blitHardwareHints(screen, show_setting); - else - GFX_blitButtonGroup((char *[]){"U/D", "SCROLL", NULL}, 0, screen, 0); - - GFX_blitButtonGroup((char *[]){"B", "BACK", NULL}, 1, screen, 1); - - GFX_flip(screen); - dirty = 0; - } - else { - GFX_sync(); - } - } - - freeRomImages(); - free_play_activities(play_activities); - - QuitSettings(); - PWR_quit(); - PAD_quit(); - GFX_quit(); - - return EXIT_SUCCESS; + InitSettings(); + + PWR_setCPUSpeed(CPU_SPEED_MENU); + + screen = GFX_init(MODE_MAIN); + PAD_init(); + PWR_init(); + + signal(SIGINT, sigHandler); + signal(SIGTERM, sigHandler); + + play_activities = play_activity_find_all(); + LOG_debug("found %d roms\n", play_activities->count); + + initLayout(); + preloadRomImages(); + int count = play_activities->count; + int selected = 0; + int start = 0; + int end = MIN(count, layout.items_per_page); + int visible_rows = end; + + int dirty = 1; + int show_setting = 0; + while (!quit) { + uint32_t frame_start = SDL_GetTicks(); + + PAD_poll(); + + // This might be too harsh, but ignore all combos with MENU (most likely a shortcut for someone else) + if (PAD_justPressed(BTN_MENU)) { + // ? + } else { + if (PAD_justRepeated(BTN_UP)) { + selected -= 1; + if (selected < 0) { + selected = count - 1; + start = MAX(0, count - layout.items_per_page); + end = count; + } else if (selected < start) { + start -= 1; + end -= 1; + } + dirty = 1; + } else if (PAD_justRepeated(BTN_DOWN)) { + selected += 1; + if (selected >= count) { + selected = 0; + start = 0; + end = visible_rows; + } else if (selected >= end) { + start += 1; + end += 1; + } + dirty = 1; + } else if (PAD_justPressed(BTN_B)) { + quit = 1; + } + } + + PWR_update(&dirty, &show_setting, NULL, NULL); + + if (dirty) { + GFX_clear(screen); + + // title pill + { + int max_width = screen->w - SCALE1(PADDING * 2); + if (screen->w >= SCALE1(320)) { + int ow = GFX_blitHardwareGroup(screen, show_setting); + max_width = screen->w - SCALE1(PADDING * 2) - ow; + } + + int play_time_total = play_activities->play_time_total; + char play_time_total_formatted[255]; + serializeTime(play_time_total_formatted, play_time_total); + char display_name[256]; + sprintf(display_name, "Time spent having fun: %s", play_time_total_formatted); + + char title[256]; + int text_width = + GFX_truncateText(font.large, display_name, title, max_width, SCALE1(BUTTON_PADDING * 2)); + max_width = MIN(max_width, text_width); + + SDL_Surface *text; + text = TTF_RenderUTF8_Blended(font.large, title, COLOR_WHITE); + GFX_blitPill(ASSET_BLACK_PILL, screen, + &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); + SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, + &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); + SDL_FreeSurface(text); + } + + renderList(count, start, end, selected); + + if (show_setting) + GFX_blitHardwareHints(screen, show_setting); + else + GFX_blitButtonGroup((char *[]){"U/D", "SCROLL", NULL}, 0, screen, 0); + + GFX_blitButtonGroup((char *[]){"B", "BACK", NULL}, 1, screen, 1); + + GFX_flip(screen); + dirty = 0; + } else { + GFX_sync(); + } + } + + freeRomImages(); + free_play_activities(play_activities); + + QuitSettings(); + PWR_quit(); + PAD_quit(); + GFX_quit(); + + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/workspace/all/gametimectl/gametimectl.c b/workspace/all/gametimectl/gametimectl.c index 9b030b76c..909c87536 100644 --- a/workspace/all/gametimectl/gametimectl.c +++ b/workspace/all/gametimectl/gametimectl.c @@ -10,60 +10,53 @@ void printUsage() { - printf("Usage: gametimectl list -> List all play activities\n" - " gametimectl start [rom_path] -> Launch the counter for this rom\n" - " gametimectl resume -> Resume the last rom as a new play activity\n" - " gametimectl stop [rom_path] -> Stop the counter for this rom\n" - " gametimectl stop_all -> Stop the counter for all roms\n"); + printf("Usage: gametimectl list -> List all play activities\n" + " gametimectl start [rom_path] -> Launch the counter for this rom\n" + " gametimectl resume -> Resume the last rom as a new play activity\n" + " gametimectl stop [rom_path] -> Stop the counter for this rom\n" + " gametimectl stop_all -> Stop the counter for all roms\n"); } int main(int argc, char *argv[]) { - if (argc <= 1) { - printUsage(); - return EXIT_SUCCESS; - } + if (argc <= 1) { + printUsage(); + return EXIT_SUCCESS; + } - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "start") == 0) { - if (i + 1 < argc) { - LOG_info("Start tracking: %s\n", argv[i+1]); - play_activity_start(argv[++i]); - } - else { - printf("Error: Missing rom_path argument\n"); - printUsage(); - return EXIT_FAILURE; - } - } - else if (strcmp(argv[i], "resume") == 0) { - LOG_info("Resuming tracking for last game\n"); - play_activity_resume(); - } - else if (strcmp(argv[i], "stop") == 0) { - if (i + 1 < argc) { - LOG_info("Stop tracking: %s\n", argv[i+1]); - play_activity_stop(argv[++i]); - } - else { - printf("Error: Missing rom_path argument\n"); - printUsage(); - return EXIT_FAILURE; - } - } - else if (strcmp(argv[i], "stop_all") == 0) { - LOG_info("Stopping tracking for all games\n"); - play_activity_stop_all(); - } - else if (strcmp(argv[i], "list") == 0) { - play_activity_list_all(); - } - else { - printf("Error: Invalid argument '%s'\n", argv[1]); - printUsage(); - return EXIT_FAILURE; - } - } + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "start") == 0) { + if (i + 1 < argc) { + LOG_info("Start tracking: %s\n", argv[i + 1]); + play_activity_start(argv[++i]); + } else { + printf("Error: Missing rom_path argument\n"); + printUsage(); + return EXIT_FAILURE; + } + } else if (strcmp(argv[i], "resume") == 0) { + LOG_info("Resuming tracking for last game\n"); + play_activity_resume(); + } else if (strcmp(argv[i], "stop") == 0) { + if (i + 1 < argc) { + LOG_info("Stop tracking: %s\n", argv[i + 1]); + play_activity_stop(argv[++i]); + } else { + printf("Error: Missing rom_path argument\n"); + printUsage(); + return EXIT_FAILURE; + } + } else if (strcmp(argv[i], "stop_all") == 0) { + LOG_info("Stopping tracking for all games\n"); + play_activity_stop_all(); + } else if (strcmp(argv[i], "list") == 0) { + play_activity_list_all(); + } else { + printf("Error: Invalid argument '%s'\n", argv[1]); + printUsage(); + return EXIT_FAILURE; + } + } - return EXIT_SUCCESS; + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/workspace/all/ledcontrol/ledcontrol.c b/workspace/all/ledcontrol/ledcontrol.c index aff2cd35c..fae73d870 100644 --- a/workspace/all/ledcontrol/ledcontrol.c +++ b/workspace/all/ledcontrol/ledcontrol.c @@ -13,384 +13,361 @@ const char *lightnames[4]; #define NROF_TRIGGERS 14 -const char *triggernames[] = { - "B", "A", "Y", "X", "L", "R", "FN1", "FN2", "MENU", "SELECT", "START", "ALL", "LR", "DPAD"}; - -const char *effect_names[] = { - "Linear", "Breathe", "Interval Breathe", "Static", - "Blink 1", "Blink 2", "Blink 3", "Rainbow", "Twinkle", - "Fire", "Glitter", "NeonGlow", "Firefly", "Aurora", "Reactive"}; -const char *topbar_effect_names[] = { - "Linear", "Breathe", "Interval Breathe", "Static", - "Blink 1", "Blink 2", "Blink 3", "Rainbow", "Twinkle", - "Fire", "Glitter", "NeonGlow", "Firefly", "Aurora", "Reactive", "Topbar Rainbow", "Topbar night"}; -const char *lr_effect_names[] = { - "Linear", "Breathe", "Interval Breathe", "Static", - "Blink 1", "Blink 2", "Blink 3", "Rainbow", "Twinkle", - "Fire", "Glitter", "NeonGlow", "Firefly", "Aurora", "Reactive", "LR Rainbow", "LR Reactive"}; - -void save_settings() { - LOG_debug("saving settings plat\n"); - char diskfilename[256]; - char* device = getenv("DEVICE"); - is_brick = exactMatch("brick", device); - int maxlights = 4; - // TODO: this shouldnt be in shared userdata - if(is_brick) { - snprintf(diskfilename, sizeof(diskfilename), SHARED_USERDATA_PATH "/ledsettings_brick.txt"); - } - else { - maxlights = 3; - snprintf(diskfilename, sizeof(diskfilename), SHARED_USERDATA_PATH "/ledsettings.txt"); - } - - FILE *file = fopen(diskfilename, "w"); - - if (file == NULL) - { - perror("Unable to open settings file for writing"); - } else { - LOG_debug("saving leds!\n"); - for (int i = 0; i < maxlights; ++i) - { - fprintf(file, "[%s]\n", lightsDefault[i].name); - fprintf(file, "effect=%d\n", lightsDefault[i].effect); - fprintf(file, "color1=0x%06X\n", lightsDefault[i].color1); - fprintf(file, "color2=0x%06X\n", lightsDefault[i].color2); - fprintf(file, "speed=%d\n", lightsDefault[i].speed); - fprintf(file, "brightness=%d\n", lightsDefault[i].brightness); - fprintf(file, "trigger=%d\n", lightsDefault[i].trigger); - fprintf(file, "filename=%s\n", lightsDefault[i].filename); - fprintf(file, "inbrightness=%i\n", lightsDefault[i].inbrightness); - fprintf(file, "\n"); // added last extra break seperate because everytime i add another option i forget to change it lol - } - - fclose(file); - } +const char *triggernames[] = {"B", "A", "Y", "X", "L", "R", "FN1", + "FN2", "MENU", "SELECT", "START", "ALL", "LR", "DPAD"}; + +const char *effect_names[] = {"Linear", "Breathe", "Interval Breathe", "Static", "Blink 1", + "Blink 2", "Blink 3", "Rainbow", "Twinkle", "Fire", + "Glitter", "NeonGlow", "Firefly", "Aurora", "Reactive"}; +const char *topbar_effect_names[] = {"Linear", "Breathe", "Interval Breathe", "Static", "Blink 1", + "Blink 2", "Blink 3", "Rainbow", "Twinkle", "Fire", + "Glitter", "NeonGlow", "Firefly", "Aurora", "Reactive", + "Topbar Rainbow", "Topbar night"}; +const char *lr_effect_names[] = {"Linear", "Breathe", "Interval Breathe", "Static", "Blink 1", "Blink 2", + "Blink 3", "Rainbow", "Twinkle", "Fire", "Glitter", "NeonGlow", + "Firefly", "Aurora", "Reactive", "LR Rainbow", "LR Reactive"}; + +void save_settings() +{ + LOG_debug("saving settings plat\n"); + char diskfilename[256]; + char *device = getenv("DEVICE"); + is_brick = exactMatch("brick", device); + int maxlights = 4; + // TODO: this shouldnt be in shared userdata + if (is_brick) { + snprintf(diskfilename, sizeof(diskfilename), SHARED_USERDATA_PATH "/ledsettings_brick.txt"); + } else { + maxlights = 3; + snprintf(diskfilename, sizeof(diskfilename), SHARED_USERDATA_PATH "/ledsettings.txt"); + } + + FILE *file = fopen(diskfilename, "w"); + + if (file == NULL) { + perror("Unable to open settings file for writing"); + } else { + LOG_debug("saving leds!\n"); + for (int i = 0; i < maxlights; ++i) { + fprintf(file, "[%s]\n", lightsDefault[i].name); + fprintf(file, "effect=%d\n", lightsDefault[i].effect); + fprintf(file, "color1=0x%06X\n", lightsDefault[i].color1); + fprintf(file, "color2=0x%06X\n", lightsDefault[i].color2); + fprintf(file, "speed=%d\n", lightsDefault[i].speed); + fprintf(file, "brightness=%d\n", lightsDefault[i].brightness); + fprintf(file, "trigger=%d\n", lightsDefault[i].trigger); + fprintf(file, "filename=%s\n", lightsDefault[i].filename); + fprintf(file, "inbrightness=%i\n", lightsDefault[i].inbrightness); + fprintf(file, "\n"); // added last extra break seperate because everytime i add another option i forget to + // change it lol + } + + fclose(file); + } } - + void handle_light_input(LightSettings *light, SDL_Event *event, int selected_setting) { - const uint32_t bright_colors[] = { - // Blues - 0x000011, 0x000022, 0x000033, 0x000044, 0x000055, 0x000066, 0x000077, 0x000088, 0x000099, 0x0000AA, 0x0000BB, 0x0000CC, 0x3366FF, 0x4D7AFF, 0x6699FF, 0x80B3FF, 0x99CCFF, 0xB3D9FF, 0x0000FF, - // Cyan - 0x001111, 0x002222, 0x003333, 0x004444, 0x005555, 0x006666, 0x007777, 0x008888, 0x009999, 0x00AAAA, 0x00BBBB, 0x00CCCC, 0x33FFFF, 0x4DFFFF, 0x66FFFF, 0x80FFFF, 0x99FFFF, 0xB3FFFF, 0x00FFFF, - // Green - 0x001100, 0x002200, 0x003300, 0x004400, 0x005500, 0x006600, 0x007700, 0x008800, 0x009900, 0x00AA00, 0x00BB00, 0x00CC00, 0x33FF33, 0x4DFF4D, 0x66FF66, 0x80FF80, 0x99FF99, 0xB3FFB3, 0x00FF00, - // Magenta - 0x110011, 0x220022, 0x330033, 0x440044, 0x550055, 0x660066, 0x770077, 0x880088, 0x990099, 0xAA00AA, 0xBB00BB, 0xCC00CC, 0xFF33FF, 0xFF4DFF, 0xFF66FF, 0xFF80FF, 0xFF99FF, 0xFFB3FF, 0xFF00FF, - // Purple - 0x220044, 0x330066, 0x440088, 0x5500AA, 0x6600CC, 0x7700DD, 0x8800EE, 0x9900FF, 0xAA00FF, 0xBB00FF, 0xCC00FF, 0x8833FF, 0x994DFF, 0xAA66FF, 0xBB80FF, 0xCC99FF, 0xDDB3FF, - // Red - 0x220000, 0x440000, 0x660000, 0x880000, 0xAA0000, 0xCC0000, 0xFF3333, 0xFF4D4D, 0xFF6666, 0xFF8080, 0xFF9999, 0xFFB3B3, 0xFF0000, - // Yellow - 0x222200, 0x444400, 0x666600, 0x888800, 0xAAAA00, 0xCCCC00, 0xFFFF33, 0xFFFF4D, 0xFFFF66, 0xFFFF80, 0xFFFF99, 0xFFFFB3, 0xFFFF00, - // Orange - 0x331100, 0x662200, 0x993300, 0xCC4400, 0xFF5500, 0xFF6600, 0xFF7711, 0xFF8822, 0xFF9933, 0xFFAA44, 0xFFBB55, 0xFFCC66, 0xFFDD77, 0xFFEE88, - // White to Black Gradient - 0x000000, 0x111111, 0x222222, 0x333333, 0x444444, 0x555555, 0x666666, 0x777777, 0x888888, 0x999999, 0xAAAAAA, 0xBBBBBB, 0xCCCCCC, 0xDDDDDD, 0xFFFFFF - }; - - const int num_bright_colors = sizeof(bright_colors) / sizeof(bright_colors[0]); - - switch (selected_setting) - { - case 0: // Effect - if (PAD_justPressed(BTN_RIGHT)) - { - light->effect = (light->effect % 6) + 1; // Increase effect (1 to 8) - } - else if (PAD_justPressed(BTN_LEFT)) - { - light->effect = (light->effect - 2 + 6) % 6 + 1; // Decrease effect (1 to 8) - } - break; - case 1: // Color - if (PAD_justPressed(BTN_RIGHT)) - { - int current_index = -1; - for (int i = 0; i < num_bright_colors; i++) - { - if (bright_colors[i] == light->color1) - { - current_index = i; - break; - } - } - light->color1 = bright_colors[(current_index + 1) % num_bright_colors]; - } - else if (PAD_justPressed(BTN_LEFT)) - { - int current_index = -1; - for (int i = 0; i < num_bright_colors; i++) - { - if (bright_colors[i] == light->color1) - { - current_index = i; - break; - } - } - light->color1 = bright_colors[(current_index - 1 + num_bright_colors) % num_bright_colors]; - } - break; - // case 2: // Color2 - // if (PAD_justPressed(BTN_RIGHT)) - // { - // int current_index = -1; - // for (int i = 0; i < num_bright_colors; i++) - // { - // if (bright_colors[i] == light->color2) - // { - // current_index = i; - // break; - // } - // } - // SDL_Log("saved settings to disk and shm %d", current_index); - // light->color2 = bright_colors[(current_index + 1) % num_bright_colors]; - // } - // else if (PAD_justPressed(BTN_LEFT)) - // { - // int current_index = -1; - // for (int i = 0; i < num_bright_colors; i++) - // { - // if (bright_colors[i] == light->color2) - // { - // current_index = i; - // break; - // } - // } - // light->color2 = bright_colors[(current_index - 1 + num_bright_colors) % num_bright_colors]; - // } - // break; - case 2: // Duration - if (PAD_justPressed(BTN_RIGHT)) - { - light->speed = (light->speed + 100) % 5000; // Increase duration - } - else if (PAD_justPressed(BTN_LEFT)) - { - light->speed = (light->speed - 100 + 5000) % 5000; // Decrease duration - } - break; - case 3: // Brightness - if (PAD_justPressed(BTN_RIGHT)) - { - light->brightness = (light->brightness + 5) % 105; // Increase duration - } - else if (PAD_justPressed(BTN_LEFT)) - { - light->brightness = (light->brightness - 5 + 105) % 105; // Decrease duration - } - break; - case 4: // Info Brightness - if (PAD_justPressed(BTN_RIGHT)) - { - light->inbrightness = (light->inbrightness + 5) % 105; // Increase duration - } - else if (PAD_justPressed(BTN_LEFT)) - { - light->inbrightness = (light->inbrightness - 5 + 105) % 105; // Decrease duration - } - break; - case 5: // trigger - if (PAD_justPressed(BTN_RIGHT)) - { - light->trigger = (light->trigger % NROF_TRIGGERS) + 1; // Increase effect (1 to 8) - } - else if (PAD_justPressed(BTN_LEFT)) - { - light->trigger = (light->trigger - 2 + NROF_TRIGGERS) % NROF_TRIGGERS + 1; // Decrease effect (1 to 8) - } - break; - } - - // Save settings after each change - LEDS_setProfile(LIGHT_PROFILE_DEFAULT); - LEDS_updateLeds(false); - save_settings(); + const uint32_t bright_colors[] = { + // Blues + 0x000011, 0x000022, 0x000033, 0x000044, 0x000055, 0x000066, 0x000077, 0x000088, 0x000099, 0x0000AA, 0x0000BB, + 0x0000CC, 0x3366FF, 0x4D7AFF, 0x6699FF, 0x80B3FF, 0x99CCFF, 0xB3D9FF, 0x0000FF, + // Cyan + 0x001111, 0x002222, 0x003333, 0x004444, 0x005555, 0x006666, 0x007777, 0x008888, 0x009999, 0x00AAAA, 0x00BBBB, + 0x00CCCC, 0x33FFFF, 0x4DFFFF, 0x66FFFF, 0x80FFFF, 0x99FFFF, 0xB3FFFF, 0x00FFFF, + // Green + 0x001100, 0x002200, 0x003300, 0x004400, 0x005500, 0x006600, 0x007700, 0x008800, 0x009900, 0x00AA00, 0x00BB00, + 0x00CC00, 0x33FF33, 0x4DFF4D, 0x66FF66, 0x80FF80, 0x99FF99, 0xB3FFB3, 0x00FF00, + // Magenta + 0x110011, 0x220022, 0x330033, 0x440044, 0x550055, 0x660066, 0x770077, 0x880088, 0x990099, 0xAA00AA, 0xBB00BB, + 0xCC00CC, 0xFF33FF, 0xFF4DFF, 0xFF66FF, 0xFF80FF, 0xFF99FF, 0xFFB3FF, 0xFF00FF, + // Purple + 0x220044, 0x330066, 0x440088, 0x5500AA, 0x6600CC, 0x7700DD, 0x8800EE, 0x9900FF, 0xAA00FF, 0xBB00FF, 0xCC00FF, + 0x8833FF, 0x994DFF, 0xAA66FF, 0xBB80FF, 0xCC99FF, 0xDDB3FF, + // Red + 0x220000, 0x440000, 0x660000, 0x880000, 0xAA0000, 0xCC0000, 0xFF3333, 0xFF4D4D, 0xFF6666, 0xFF8080, 0xFF9999, + 0xFFB3B3, 0xFF0000, + // Yellow + 0x222200, 0x444400, 0x666600, 0x888800, 0xAAAA00, 0xCCCC00, 0xFFFF33, 0xFFFF4D, 0xFFFF66, 0xFFFF80, 0xFFFF99, + 0xFFFFB3, 0xFFFF00, + // Orange + 0x331100, 0x662200, 0x993300, 0xCC4400, 0xFF5500, 0xFF6600, 0xFF7711, 0xFF8822, 0xFF9933, 0xFFAA44, 0xFFBB55, + 0xFFCC66, 0xFFDD77, 0xFFEE88, + // White to Black Gradient + 0x000000, 0x111111, 0x222222, 0x333333, 0x444444, 0x555555, 0x666666, 0x777777, 0x888888, 0x999999, 0xAAAAAA, + 0xBBBBBB, 0xCCCCCC, 0xDDDDDD, 0xFFFFFF}; + + const int num_bright_colors = sizeof(bright_colors) / sizeof(bright_colors[0]); + + switch (selected_setting) { + case 0: // Effect + if (PAD_justPressed(BTN_RIGHT)) { + light->effect = (light->effect % 6) + 1; // Increase effect (1 to 8) + } else if (PAD_justPressed(BTN_LEFT)) { + light->effect = (light->effect - 2 + 6) % 6 + 1; // Decrease effect (1 to 8) + } + break; + case 1: // Color + if (PAD_justPressed(BTN_RIGHT)) { + int current_index = -1; + for (int i = 0; i < num_bright_colors; i++) { + if (bright_colors[i] == light->color1) { + current_index = i; + break; + } + } + light->color1 = bright_colors[(current_index + 1) % num_bright_colors]; + } else if (PAD_justPressed(BTN_LEFT)) { + int current_index = -1; + for (int i = 0; i < num_bright_colors; i++) { + if (bright_colors[i] == light->color1) { + current_index = i; + break; + } + } + light->color1 = bright_colors[(current_index - 1 + num_bright_colors) % num_bright_colors]; + } + break; + // case 2: // Color2 + // if (PAD_justPressed(BTN_RIGHT)) + // { + // int current_index = -1; + // for (int i = 0; i < num_bright_colors; i++) + // { + // if (bright_colors[i] == light->color2) + // { + // current_index = i; + // break; + // } + // } + // SDL_Log("saved settings to disk and shm %d", current_index); + // light->color2 = bright_colors[(current_index + 1) % num_bright_colors]; + // } + // else if (PAD_justPressed(BTN_LEFT)) + // { + // int current_index = -1; + // for (int i = 0; i < num_bright_colors; i++) + // { + // if (bright_colors[i] == light->color2) + // { + // current_index = i; + // break; + // } + // } + // light->color2 = bright_colors[(current_index - 1 + num_bright_colors) % num_bright_colors]; + // } + // break; + case 2: // Duration + if (PAD_justPressed(BTN_RIGHT)) { + light->speed = (light->speed + 100) % 5000; // Increase duration + } else if (PAD_justPressed(BTN_LEFT)) { + light->speed = (light->speed - 100 + 5000) % 5000; // Decrease duration + } + break; + case 3: // Brightness + if (PAD_justPressed(BTN_RIGHT)) { + light->brightness = (light->brightness + 5) % 105; // Increase duration + } else if (PAD_justPressed(BTN_LEFT)) { + light->brightness = (light->brightness - 5 + 105) % 105; // Decrease duration + } + break; + case 4: // Info Brightness + if (PAD_justPressed(BTN_RIGHT)) { + light->inbrightness = (light->inbrightness + 5) % 105; // Increase duration + } else if (PAD_justPressed(BTN_LEFT)) { + light->inbrightness = (light->inbrightness - 5 + 105) % 105; // Decrease duration + } + break; + case 5: // trigger + if (PAD_justPressed(BTN_RIGHT)) { + light->trigger = (light->trigger % NROF_TRIGGERS) + 1; // Increase effect (1 to 8) + } else if (PAD_justPressed(BTN_LEFT)) { + light->trigger = (light->trigger - 2 + NROF_TRIGGERS) % NROF_TRIGGERS + 1; // Decrease effect (1 to 8) + } + break; + } + + // Save settings after each change + LEDS_setProfile(LIGHT_PROFILE_DEFAULT); + LEDS_updateLeds(false); + save_settings(); } int main(int argc, char *argv[]) { - char* device = getenv("DEVICE"); - is_brick = exactMatch("brick", device); - + char *device = getenv("DEVICE"); + is_brick = exactMatch("brick", device); + InitSettings(); - PWR_setCPUSpeed(CPU_SPEED_MENU); - - if (is_brick) { - const char *brick_names[] = {"F1 key", "F2 key", "Top bar", "L&R triggers"}; - memcpy(lightnames, brick_names, sizeof(brick_names)); // Copy values - } else { - const char *default_names[] = {"Joystick L","Joystick R", "Logo"}; - memcpy(lightnames, default_names, sizeof(default_names)); // Copy values - } - - SDL_Surface* screen = GFX_init(MODE_MENU); + PWR_setCPUSpeed(CPU_SPEED_MENU); + + if (is_brick) { + const char *brick_names[] = {"F1 key", "F2 key", "Top bar", "L&R triggers"}; + memcpy(lightnames, brick_names, sizeof(brick_names)); // Copy values + } else { + const char *default_names[] = {"Joystick L", "Joystick R", "Logo"}; + memcpy(lightnames, default_names, sizeof(default_names)); // Copy values + } + + SDL_Surface *screen = GFX_init(MODE_MENU); PAD_init(); PWR_init(); - GFX_clearAll(); + GFX_clearAll(); GFX_clearLayers(0); GFX_flip(screen); - bool running = true; - int selected_light = 0; - int selected_setting = 0; - SDL_Event event; - int quit = 0; + bool running = true; + int selected_light = 0; + int selected_setting = 0; + SDL_Event event; + int quit = 0; int dirty = 1; - int show_setting = 0; // 1=brightness,2=volume,3=colortemp - int was_online = PLAT_isOnline(); - int had_bt = PLAT_btIsConnected(); - - while (!quit) - { - GFX_startFrame(); - uint32_t frame_start = SDL_GetTicks(); - + int show_setting = 0; // 1=brightness,2=volume,3=colortemp + int was_online = PLAT_isOnline(); + int had_bt = PLAT_btIsConnected(); + + while (!quit) { + GFX_startFrame(); + uint32_t frame_start = SDL_GetTicks(); + PAD_poll(); - PWR_update(&dirty, &show_setting, NULL, NULL); - - int is_online = PLAT_isOnline(); - if (was_online!=is_online) - dirty = 1; + PWR_update(&dirty, &show_setting, NULL, NULL); + + int is_online = PLAT_isOnline(); + if (was_online != is_online) + dirty = 1; was_online = is_online; - int has_bt = PLAT_btIsConnected(); - if (had_bt != has_bt) - dirty = 1; - had_bt = has_bt; - - int numOfLights = 3; - if(is_brick) numOfLights = 4; - - if (PAD_justPressed(BTN_B)) { - quit = 1; - } - else if(PAD_justPressed(BTN_DOWN)) { - selected_setting = (selected_setting + 1) % NUM_MAIN_OPTIONS; - dirty = 1; - } - else if(PAD_justPressed(BTN_UP)) { - selected_setting = (selected_setting - 1 + NUM_MAIN_OPTIONS) % NUM_MAIN_OPTIONS; - dirty = 1; - } - else if(PAD_justPressed(BTN_L1)) { - selected_light = (selected_light - 1 + numOfLights) % numOfLights; - dirty = 1; - } - else if(PAD_justPressed(BTN_R1)) { - selected_light = (selected_light + 1) % numOfLights; - dirty = 1; - } - else if(PAD_justPressed(BTN_LEFT) || PAD_justPressed(BTN_RIGHT)) { - handle_light_input(&lightsDefault[selected_light],&event, selected_setting); - dirty = 1; - } - - if (dirty) { - GFX_clear(screen); - - int ow = GFX_blitHardwareGroup(screen, show_setting); - - if (show_setting) GFX_blitHardwareHints(screen, show_setting); - - GFX_blitButtonGroup((char*[]){ "B","BACK", NULL }, 1, screen, 1); - GFX_blitButtonGroup((char*[]){ "L/R","Select light", NULL }, 0, screen, 0); - - - int max_width = screen->w - SCALE1(PADDING * 2) - ow; - // Display light name - char light_name_text[256]; - snprintf(light_name_text, sizeof(light_name_text), "%s", lightnames[selected_light]); - - char title[256]; - int text_width = GFX_truncateText(font.medium, light_name_text, title, max_width, SCALE1(BUTTON_PADDING * 2)); - max_width = MIN(max_width, text_width); - - SDL_Surface *text; - text = TTF_RenderUTF8_Blended(font.medium, title, COLOR_WHITE); - GFX_blitPill(ASSET_BLACK_PILL, screen, &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); - SDL_FreeSurface(text); - - // Display settings - // const char *settings_labels[6] = {"Effect", "Color", "Color2", "Speed", "Brightness", "Trigger"}; - // this stuff is really not multiplatform at all, need to figure out a way so its not so TrimUI specific - const char *settings_labels[5]; // Define array with correct size - if (is_brick) { - const char *brick_labels[] = {"Effect", "Color", "Speed", "Brightness", "Info brightness"}; - memcpy(settings_labels, brick_labels, sizeof(brick_labels)); // Copy values - } else { - const char *non_brick_labels[] = {"Effect", "Color", "Speed", "Brightness (All Leds)", "Info brightness (All Leds)"}; - memcpy(settings_labels, non_brick_labels, sizeof(non_brick_labels)); // Copy values - } - int settings_values[5] = { - lightsDefault[selected_light].effect, - lightsDefault[selected_light].color1, - lightsDefault[selected_light].speed, - lightsDefault[selected_light].brightness, - lightsDefault[selected_light].inbrightness - }; - - for (int j = 0; j < 5; ++j) - { - char setting_text[256]; - bool selected = (j == selected_setting); - SDL_Color current_color = selected ? COLOR_BLACK : COLOR_WHITE; - - int y = SCALE1(PADDING + PILL_SIZE * (j + 1)); - - if (j == 0) { // Display effect name instead of number - snprintf(setting_text, sizeof(setting_text), "%s: %s", settings_labels[j], selected_light == 3 ? lr_effect_names[settings_values[j] - 1] : selected_light == 2 ? topbar_effect_names[settings_values[j] - 1] : effect_names[settings_values[j] - 1]); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); - int text_width = text->w + SCALE1(BUTTON_PADDING * 2); - GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, - &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, - &(SDL_Rect){0, 0, text->w, text->h}, screen, - &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); - SDL_FreeSurface(text); - } else if (j == 1) { // Display color as hex code - snprintf(setting_text, sizeof(setting_text), "%s", settings_labels[j]); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); - int text_width = text->w + SCALE1(BUTTON_PADDING * 2); - GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, - &(SDL_Rect){SCALE1(PADDING), y, text_width + SCALE1(BUTTON_MARGIN + BUTTON_SIZE), SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, - &(SDL_Rect){0, 0, text->w, text->h}, screen, - &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); - SDL_FreeSurface(text); - - GFX_blitAssetColor(ASSET_BUTTON, NULL, screen, &(SDL_Rect){ - SCALE1(PADDING) + text_width, - y + SCALE1(BUTTON_MARGIN) - }, settings_values[j]); - } else { - snprintf(setting_text, sizeof(setting_text), "%s: %d", settings_labels[j], settings_values[j]); - SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); - int text_width = text->w + SCALE1(BUTTON_PADDING * 2); - GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, - &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); - SDL_BlitSurface(text, - &(SDL_Rect){0, 0, text->w, text->h}, screen, - &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); - SDL_FreeSurface(text); - } - } - - GFX_flip(screen); - dirty = 0; - } - else GFX_delay(); - } + int has_bt = PLAT_btIsConnected(); + if (had_bt != has_bt) + dirty = 1; + had_bt = has_bt; + + int numOfLights = 3; + if (is_brick) + numOfLights = 4; + + if (PAD_justPressed(BTN_B)) { + quit = 1; + } else if (PAD_justPressed(BTN_DOWN)) { + selected_setting = (selected_setting + 1) % NUM_MAIN_OPTIONS; + dirty = 1; + } else if (PAD_justPressed(BTN_UP)) { + selected_setting = (selected_setting - 1 + NUM_MAIN_OPTIONS) % NUM_MAIN_OPTIONS; + dirty = 1; + } else if (PAD_justPressed(BTN_L1)) { + selected_light = (selected_light - 1 + numOfLights) % numOfLights; + dirty = 1; + } else if (PAD_justPressed(BTN_R1)) { + selected_light = (selected_light + 1) % numOfLights; + dirty = 1; + } else if (PAD_justPressed(BTN_LEFT) || PAD_justPressed(BTN_RIGHT)) { + handle_light_input(&lightsDefault[selected_light], &event, selected_setting); + dirty = 1; + } + + if (dirty) { + GFX_clear(screen); + + int ow = GFX_blitHardwareGroup(screen, show_setting); + + if (show_setting) + GFX_blitHardwareHints(screen, show_setting); + + GFX_blitButtonGroup((char *[]){"B", "BACK", NULL}, 1, screen, 1); + GFX_blitButtonGroup((char *[]){"L/R", "Select light", NULL}, 0, screen, 0); + + + int max_width = screen->w - SCALE1(PADDING * 2) - ow; + // Display light name + char light_name_text[256]; + snprintf(light_name_text, sizeof(light_name_text), "%s", lightnames[selected_light]); + + char title[256]; + int text_width = + GFX_truncateText(font.medium, light_name_text, title, max_width, SCALE1(BUTTON_PADDING * 2)); + max_width = MIN(max_width, text_width); + + SDL_Surface *text; + text = TTF_RenderUTF8_Blended(font.medium, title, COLOR_WHITE); + GFX_blitPill(ASSET_BLACK_PILL, screen, + &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), max_width, SCALE1(PILL_SIZE)}); + SDL_BlitSurface(text, &(SDL_Rect){0, 0, max_width - SCALE1(BUTTON_PADDING * 2), text->h}, screen, + &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), SCALE1(PADDING + 4)}); + SDL_FreeSurface(text); + + // Display settings + // const char *settings_labels[6] = {"Effect", "Color", "Color2", "Speed", "Brightness", "Trigger"}; + // this stuff is really not multiplatform at all, need to figure out a way so its not so TrimUI specific + const char *settings_labels[5]; // Define array with correct size + if (is_brick) { + const char *brick_labels[] = {"Effect", "Color", "Speed", "Brightness", "Info brightness"}; + memcpy(settings_labels, brick_labels, sizeof(brick_labels)); // Copy values + } else { + const char *non_brick_labels[] = {"Effect", "Color", "Speed", "Brightness (All Leds)", + "Info brightness (All Leds)"}; + memcpy(settings_labels, non_brick_labels, sizeof(non_brick_labels)); // Copy values + } + int settings_values[5] = {lightsDefault[selected_light].effect, lightsDefault[selected_light].color1, + lightsDefault[selected_light].speed, lightsDefault[selected_light].brightness, + lightsDefault[selected_light].inbrightness}; + + for (int j = 0; j < 5; ++j) { + char setting_text[256]; + bool selected = (j == selected_setting); + SDL_Color current_color = selected ? COLOR_BLACK : COLOR_WHITE; + + int y = SCALE1(PADDING + PILL_SIZE * (j + 1)); + + if (j == 0) { // Display effect name instead of number + snprintf(setting_text, sizeof(setting_text), "%s: %s", settings_labels[j], + selected_light == 3 ? lr_effect_names[settings_values[j] - 1] + : selected_light == 2 ? topbar_effect_names[settings_values[j] - 1] + : effect_names[settings_values[j] - 1]); + SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); + int text_width = text->w + SCALE1(BUTTON_PADDING * 2); + GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, + &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); + SDL_BlitSurface(text, &(SDL_Rect){0, 0, text->w, text->h}, screen, + &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); + SDL_FreeSurface(text); + } else if (j == 1) { // Display color as hex code + snprintf(setting_text, sizeof(setting_text), "%s", settings_labels[j]); + SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); + int text_width = text->w + SCALE1(BUTTON_PADDING * 2); + GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, + &(SDL_Rect){SCALE1(PADDING), y, text_width + SCALE1(BUTTON_MARGIN + BUTTON_SIZE), + SCALE1(PILL_SIZE)}); + SDL_BlitSurface(text, &(SDL_Rect){0, 0, text->w, text->h}, screen, + &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); + SDL_FreeSurface(text); + + GFX_blitAssetColor(ASSET_BUTTON, NULL, screen, + &(SDL_Rect){SCALE1(PADDING) + text_width, y + SCALE1(BUTTON_MARGIN)}, + settings_values[j]); + } else { + snprintf(setting_text, sizeof(setting_text), "%s: %d", settings_labels[j], settings_values[j]); + SDL_Surface *text = TTF_RenderUTF8_Blended(font.medium, setting_text, current_color); + int text_width = text->w + SCALE1(BUTTON_PADDING * 2); + GFX_blitPill(selected ? ASSET_WHITE_PILL : ASSET_BLACK_PILL, screen, + &(SDL_Rect){SCALE1(PADDING), y, text_width, SCALE1(PILL_SIZE)}); + SDL_BlitSurface(text, &(SDL_Rect){0, 0, text->w, text->h}, screen, + &(SDL_Rect){SCALE1(PADDING + BUTTON_PADDING), y + SCALE1(4)}); + SDL_FreeSurface(text); + } + } + + GFX_flip(screen); + dirty = 0; + } else + GFX_delay(); + } PWR_quit(); PAD_quit(); GFX_quit(); - QuitSettings(); + QuitSettings(); - return 0; + return 0; } diff --git a/workspace/all/libbatmondb/batmondb.c b/workspace/all/libbatmondb/batmondb.c index 598eed438..46120e077 100644 --- a/workspace/all/libbatmondb/batmondb.c +++ b/workspace/all/libbatmondb/batmondb.c @@ -12,66 +12,67 @@ #define BATTERY_LOG_PATH SHARED_USERDATA_PATH #define BATTERY_LOG_FILE BATTERY_LOG_PATH "/battery_logs.sqlite" -sqlite3* open_battery_log_db(void) +sqlite3 *open_battery_log_db(void) { - mkdir(BATTERY_LOG_PATH, 0755); - bool db_exists = exists(BATTERY_LOG_FILE); - if (!db_exists) - touch(BATTERY_LOG_FILE); + mkdir(BATTERY_LOG_PATH, 0755); + bool db_exists = exists(BATTERY_LOG_FILE); + if (!db_exists) + touch(BATTERY_LOG_FILE); - sqlite3 *bat_log_db = NULL; + sqlite3 *bat_log_db = NULL; - if (sqlite3_open(BATTERY_LOG_FILE, &bat_log_db) != SQLITE_OK) { - printf("%s\n", sqlite3_errmsg(bat_log_db)); - close_battery_log_db(bat_log_db); - return NULL; - } + if (sqlite3_open(BATTERY_LOG_FILE, &bat_log_db) != SQLITE_OK) { + printf("%s\n", sqlite3_errmsg(bat_log_db)); + close_battery_log_db(bat_log_db); + return NULL; + } - if (!db_exists) { - sqlite3_exec(bat_log_db, - "DROP TABLE IF EXISTS bat_activity;" - "CREATE TABLE bat_activity(id INTEGER PRIMARY KEY, device_serial TEXT, bat_level INTEGER, duration INTEGER, is_charging INTEGER);" - "CREATE INDEX bat_activity_device_SN_index ON bat_activity(device_serial);", - NULL, NULL, NULL); - sqlite3_exec(bat_log_db, - "DROP TABLE IF EXISTS device_specifics;" - "CREATE TABLE device_specifics(id INTEGER PRIMARY KEY, device_serial TEXT, best_session INTEGER);" - "CREATE INDEX device_specifics_index ON device_specifics(device_serial);", - NULL, NULL, NULL); - } + if (!db_exists) { + sqlite3_exec(bat_log_db, + "DROP TABLE IF EXISTS bat_activity;" + "CREATE TABLE bat_activity(id INTEGER PRIMARY KEY, device_serial TEXT, bat_level INTEGER, " + "duration INTEGER, is_charging INTEGER);" + "CREATE INDEX bat_activity_device_SN_index ON bat_activity(device_serial);", + NULL, NULL, NULL); + sqlite3_exec(bat_log_db, + "DROP TABLE IF EXISTS device_specifics;" + "CREATE TABLE device_specifics(id INTEGER PRIMARY KEY, device_serial TEXT, best_session INTEGER);" + "CREATE INDEX device_specifics_index ON device_specifics(device_serial);", + NULL, NULL, NULL); + } - return bat_log_db; + return bat_log_db; } -void close_battery_log_db(sqlite3* bat_log_db) +void close_battery_log_db(sqlite3 *bat_log_db) { - sqlite3_close(bat_log_db); - bat_log_db = NULL; + sqlite3_close(bat_log_db); + bat_log_db = NULL; } -int get_best_session_time(sqlite3* bat_log_db, const char* device) +int get_best_session_time(sqlite3 *bat_log_db, const char *device) { - int best_time = 0; + int best_time = 0; - if (bat_log_db != NULL) { - const char *sql = "SELECT * FROM device_specifics WHERE device_serial = ? ORDER BY id LIMIT 1;"; - sqlite3_stmt *stmt; + if (bat_log_db != NULL) { + const char *sql = "SELECT * FROM device_specifics WHERE device_serial = ? ORDER BY id LIMIT 1;"; + sqlite3_stmt *stmt; - int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); - if (rc == SQLITE_OK) { - sqlite3_bind_text(stmt, 1, device, -1, SQLITE_STATIC); - rc = sqlite3_step(stmt); - if (rc == SQLITE_ROW) { - best_time = sqlite3_column_int(stmt, 2); - } - else { - char *sql2 = sqlite3_mprintf("INSERT INTO device_specifics(device_serial, best_session) VALUES(%Q, %d);", device, 0); - sqlite3_exec(bat_log_db, sql2, NULL, NULL, NULL); - sqlite3_free(sql2); - } - } - sqlite3_finalize(stmt); - } - - return best_time; + int rc = sqlite3_prepare_v2(bat_log_db, sql, -1, &stmt, 0); + if (rc == SQLITE_OK) { + sqlite3_bind_text(stmt, 1, device, -1, SQLITE_STATIC); + rc = sqlite3_step(stmt); + if (rc == SQLITE_ROW) { + best_time = sqlite3_column_int(stmt, 2); + } else { + char *sql2 = sqlite3_mprintf( + "INSERT INTO device_specifics(device_serial, best_session) VALUES(%Q, %d);", device, 0); + sqlite3_exec(bat_log_db, sql2, NULL, NULL, NULL); + sqlite3_free(sql2); + } + } + sqlite3_finalize(stmt); + } + + return best_time; } \ No newline at end of file diff --git a/workspace/all/libbatmondb/batmondb.h b/workspace/all/libbatmondb/batmondb.h index 7483d7fdb..599dbd8e6 100644 --- a/workspace/all/libbatmondb/batmondb.h +++ b/workspace/all/libbatmondb/batmondb.h @@ -2,8 +2,8 @@ #ifndef __batmon_db_h__ #define __batmon_db_h__ -sqlite3* open_battery_log_db(void); -void close_battery_log_db(sqlite3* ctx); -int get_best_session_time(sqlite3* ctx, const char* device); +sqlite3 *open_battery_log_db(void); +void close_battery_log_db(sqlite3 *ctx); +int get_best_session_time(sqlite3 *ctx, const char *device); #endif // __batmon_db_h__ \ No newline at end of file diff --git a/workspace/all/libgametimedb/gametimedb.c b/workspace/all/libgametimedb/gametimedb.c index 0bad08717..30c94f1f8 100644 --- a/workspace/all/libgametimedb/gametimedb.c +++ b/workspace/all/libgametimedb/gametimedb.c @@ -1,4 +1,5 @@ -// heavily modified from the Onion original: https://github.com/OnionUI/Onion/blob/main/src/playActivity/playActivityDB.h +// heavily modified from the Onion original: +// https://github.com/OnionUI/Onion/blob/main/src/playActivity/playActivityDB.h #include #include #include @@ -15,456 +16,460 @@ #define GAMETIME_LOG_PATH SHARED_USERDATA_PATH #define GAMETIME_LOG_FILE GAMETIME_LOG_PATH "/game_logs.sqlite" -sqlite3* play_activity_db_open(void) +sqlite3 *play_activity_db_open(void) { - mkdir(GAMETIME_LOG_PATH, 0777); - bool db_exists = exists(GAMETIME_LOG_FILE); - if (!db_exists) - touch(GAMETIME_LOG_FILE); - - sqlite3 *game_log_db = NULL; - - if (sqlite3_open(GAMETIME_LOG_FILE, &game_log_db) != SQLITE_OK) { - printf("%s\n", sqlite3_errmsg(game_log_db)); - play_activity_db_close(game_log_db); - return NULL; - } - - if (!db_exists) { - sqlite3_exec(game_log_db, - "DROP TABLE IF EXISTS rom;" - "CREATE TABLE rom(id INTEGER PRIMARY KEY, type TEXT, name TEXT, file_path TEXT, image_path TEXT, created_at INTEGER DEFAULT (strftime('%s', 'now')), updated_at INTEGER);" - "CREATE UNIQUE INDEX rom_id_index ON rom(id);", - NULL, NULL, NULL); - sqlite3_exec(game_log_db, - "DROP TABLE IF EXISTS play_activity;" - "CREATE TABLE play_activity(rom_id INTEGER, play_time INTEGER, created_at INTEGER DEFAULT (strftime('%s', 'now')), updated_at INTEGER);" - "CREATE INDEX play_activity_rom_id_index ON play_activity(rom_id);", - NULL, NULL, NULL); - } - - return game_log_db; + mkdir(GAMETIME_LOG_PATH, 0777); + bool db_exists = exists(GAMETIME_LOG_FILE); + if (!db_exists) + touch(GAMETIME_LOG_FILE); + + sqlite3 *game_log_db = NULL; + + if (sqlite3_open(GAMETIME_LOG_FILE, &game_log_db) != SQLITE_OK) { + printf("%s\n", sqlite3_errmsg(game_log_db)); + play_activity_db_close(game_log_db); + return NULL; + } + + if (!db_exists) { + sqlite3_exec(game_log_db, + "DROP TABLE IF EXISTS rom;" + "CREATE TABLE rom(id INTEGER PRIMARY KEY, type TEXT, name TEXT, file_path TEXT, image_path TEXT, " + "created_at INTEGER DEFAULT (strftime('%s', 'now')), updated_at INTEGER);" + "CREATE UNIQUE INDEX rom_id_index ON rom(id);", + NULL, NULL, NULL); + sqlite3_exec(game_log_db, + "DROP TABLE IF EXISTS play_activity;" + "CREATE TABLE play_activity(rom_id INTEGER, play_time INTEGER, created_at INTEGER DEFAULT " + "(strftime('%s', 'now')), updated_at INTEGER);" + "CREATE INDEX play_activity_rom_id_index ON play_activity(rom_id);", + NULL, NULL, NULL); + } + + return game_log_db; } -void play_activity_db_close(sqlite3* game_log_db) +void play_activity_db_close(sqlite3 *game_log_db) { - sqlite3_close(game_log_db); - game_log_db = NULL; + sqlite3_close(game_log_db); + game_log_db = NULL; } void free_play_activities(PlayActivities *pa_ptr) { - for (int i = 0; i < pa_ptr->count; i++) { - free(pa_ptr->play_activity[i]->first_played_at); - free(pa_ptr->play_activity[i]->last_played_at); - free(pa_ptr->play_activity[i]->rom); - free(pa_ptr->play_activity[i]); - } - free(pa_ptr->play_activity); - free(pa_ptr); + for (int i = 0; i < pa_ptr->count; i++) { + free(pa_ptr->play_activity[i]->first_played_at); + free(pa_ptr->play_activity[i]->last_played_at); + free(pa_ptr->play_activity[i]->rom); + free(pa_ptr->play_activity[i]); + } + free(pa_ptr->play_activity); + free(pa_ptr); } void get_rom_image_path(char *rom_file, char *out_image_path) { - if (suffixMatch(rom_file, ".p8") || suffixMatch(rom_file, ".png")) { - snprintf(out_image_path, STR_MAX - 1, ROMS_PATH "/%s", rom_file); - } - - char *clean_rom_name = removeExtension(baseName(rom_file)); - // this assumes all media resides in a top-level .media folder - //char *rom_folder = strtok(rom_file, "/"); - //snprintf(out_image_path, STR_MAX - 1, ROMS_PATH "/%s/.media/%s.png", rom_folder, clean_rom_name); - // this assumes that roms in subfolders have corresponding game art in - // a .media folder in the respective subfolder - char rom_folder_path[MAX_PATH]; - folderPath(rom_file, rom_folder_path); - - snprintf(out_image_path, STR_MAX - 1, ROMS_PATH "/%s/.media/%s.png", rom_folder_path, clean_rom_name); - //LOG_debug("out_image_path: %s\n", out_image_path); - free(clean_rom_name); + if (suffixMatch(rom_file, ".p8") || suffixMatch(rom_file, ".png")) { + snprintf(out_image_path, STR_MAX - 1, ROMS_PATH "/%s", rom_file); + } + + char *clean_rom_name = removeExtension(baseName(rom_file)); + // this assumes all media resides in a top-level .media folder + // char *rom_folder = strtok(rom_file, "/"); + // snprintf(out_image_path, STR_MAX - 1, ROMS_PATH "/%s/.media/%s.png", rom_folder, clean_rom_name); + // this assumes that roms in subfolders have corresponding game art in + // a .media folder in the respective subfolder + char rom_folder_path[MAX_PATH]; + folderPath(rom_file, rom_folder_path); + + snprintf(out_image_path, STR_MAX - 1, ROMS_PATH "/%s/.media/%s.png", rom_folder_path, clean_rom_name); + // LOG_debug("out_image_path: %s\n", out_image_path); + free(clean_rom_name); } -int play_activity_db_transaction(sqlite3* game_log_db, int (*exec_transaction)(sqlite3*)) +int play_activity_db_transaction(sqlite3 *game_log_db, int (*exec_transaction)(sqlite3 *)) { - int retval; - retval = exec_transaction(game_log_db); - return retval; + int retval; + retval = exec_transaction(game_log_db); + return retval; } int play_activity_db_execute(char *sql) { - //LOG_info("play_activity_db_execute(%s)\n", sql); - sqlite3* game_log_db = play_activity_db_open(); - int rc = sqlite3_exec(game_log_db, sql, NULL, NULL, NULL); - play_activity_db_close(game_log_db); - return rc; + // LOG_info("play_activity_db_execute(%s)\n", sql); + sqlite3 *game_log_db = play_activity_db_open(); + int rc = sqlite3_exec(game_log_db, sql, NULL, NULL, NULL); + play_activity_db_close(game_log_db); + return rc; } -sqlite3_stmt *play_activity_db_prepare(sqlite3* game_log_db, char *sql) +sqlite3_stmt *play_activity_db_prepare(sqlite3 *game_log_db, char *sql) { - //LOG_info("play_activity_db_prepare(%s)\n", sql); - if (game_log_db == NULL) { - printf("DB is not open"); - return NULL; - } - sqlite3_stmt *stmt = NULL; - if (sqlite3_prepare_v2(game_log_db, sql, -1, &stmt, NULL) != SQLITE_OK) { - printf("%s: %s\n", sqlite3_errmsg(game_log_db), sqlite3_sql(stmt)); - } - return stmt; + // LOG_info("play_activity_db_prepare(%s)\n", sql); + if (game_log_db == NULL) { + printf("DB is not open"); + return NULL; + } + sqlite3_stmt *stmt = NULL; + if (sqlite3_prepare_v2(game_log_db, sql, -1, &stmt, NULL) != SQLITE_OK) { + printf("%s: %s\n", sqlite3_errmsg(game_log_db), sqlite3_sql(stmt)); + } + return stmt; } int play_activity_get_total_play_time(void) { - int total_play_time = 0; - char *sql = - "SELECT SUM(play_time_total) FROM (SELECT SUM(play_time) AS play_time_total FROM play_activity GROUP BY rom_id) " - "WHERE play_time_total > 60;"; - sqlite3_stmt *stmt; + int total_play_time = 0; + char *sql = "SELECT SUM(play_time_total) FROM (SELECT SUM(play_time) AS play_time_total FROM play_activity GROUP " + "BY rom_id) " + "WHERE play_time_total > 60;"; + sqlite3_stmt *stmt; - sqlite3* game_log_db = play_activity_db_open(); - stmt = play_activity_db_prepare(game_log_db, sql); + sqlite3 *game_log_db = play_activity_db_open(); + stmt = play_activity_db_prepare(game_log_db, sql); - if (sqlite3_step(stmt) == SQLITE_ROW) { - total_play_time = sqlite3_column_int(stmt, 0); - } + if (sqlite3_step(stmt) == SQLITE_ROW) { + total_play_time = sqlite3_column_int(stmt, 0); + } - sqlite3_finalize(stmt); - play_activity_db_close(game_log_db); + sqlite3_finalize(stmt); + play_activity_db_close(game_log_db); - return total_play_time; + return total_play_time; } PlayActivities *play_activity_find_all(void) { - PlayActivities *play_activities = NULL; - char *sql = - "SELECT * FROM (" - " SELECT rom.id, rom.type, rom.name, rom.file_path, " - " COUNT(play_activity.ROWID) AS play_count_total, " - " SUM(play_activity.play_time) AS play_time_total, " - " SUM(play_activity.play_time)/COUNT(play_activity.ROWID) AS play_time_average, " - " datetime(MIN(play_activity.created_at), 'unixepoch') AS first_played_at, " - " datetime(MAX(play_activity.created_at), 'unixepoch') AS last_played_at " - " FROM rom LEFT JOIN play_activity ON rom.id = play_activity.rom_id " - " GROUP BY rom.id) " - "WHERE play_time_total > 0 " - "ORDER BY play_time_total DESC;"; - sqlite3_stmt *stmt; - - sqlite3* game_log_db = play_activity_db_open(); - - stmt = play_activity_db_prepare(game_log_db, sql); - - int play_activity_count = 0; - while (sqlite3_step(stmt) == SQLITE_ROW) { - play_activity_count++; - } - sqlite3_reset(stmt); - - play_activities = (PlayActivities *)malloc(sizeof(PlayActivities)); - play_activities->count = play_activity_count; - play_activities->play_time_total = 0; - play_activities->play_activity = (PlayActivity **)malloc(sizeof(PlayActivity *) * play_activities->count); - - for (int i = 0; i < play_activities->count; i++) { - if (sqlite3_step(stmt) != SQLITE_ROW) - break; - - PlayActivity *entry = play_activities->play_activity[i] = (PlayActivity *)malloc(sizeof(PlayActivity)); - ROM *rom = play_activities->play_activity[i]->rom = (ROM *)malloc(sizeof(ROM)); - entry->first_played_at = NULL; - entry->last_played_at = NULL; - - rom->id = sqlite3_column_int(stmt, 0); - rom->type = strdup((const char *)sqlite3_column_text(stmt, 1)); - rom->name = strdup((const char *)sqlite3_column_text(stmt, 2)); - if (sqlite3_column_text(stmt, 3) != NULL) { - rom->file_path = strdup((const char *)sqlite3_column_text(stmt, 3)); - rom->image_path = malloc(STR_MAX * sizeof(char)); - memset(rom->image_path, 0, STR_MAX); - get_rom_image_path(rom->file_path, rom->image_path); - } - - entry->play_count = sqlite3_column_int(stmt, 4); - entry->play_time_total = sqlite3_column_int(stmt, 5); - entry->play_time_average = sqlite3_column_int(stmt, 6); - if (sqlite3_column_text(stmt, 8) != NULL) { - entry->first_played_at = strdup((const char *)sqlite3_column_text(stmt, 7)); - } - if (sqlite3_column_text(stmt, 9) != NULL) { - entry->last_played_at = strdup((const char *)sqlite3_column_text(stmt, 8)); - } - - play_activities->play_time_total += entry->play_time_total; - } - - sqlite3_finalize(stmt); - play_activity_db_close(game_log_db); - - return play_activities; + PlayActivities *play_activities = NULL; + char *sql = "SELECT * FROM (" + " SELECT rom.id, rom.type, rom.name, rom.file_path, " + " COUNT(play_activity.ROWID) AS play_count_total, " + " SUM(play_activity.play_time) AS play_time_total, " + " SUM(play_activity.play_time)/COUNT(play_activity.ROWID) AS play_time_average, " + " datetime(MIN(play_activity.created_at), 'unixepoch') AS first_played_at, " + " datetime(MAX(play_activity.created_at), 'unixepoch') AS last_played_at " + " FROM rom LEFT JOIN play_activity ON rom.id = play_activity.rom_id " + " GROUP BY rom.id) " + "WHERE play_time_total > 0 " + "ORDER BY play_time_total DESC;"; + sqlite3_stmt *stmt; + + sqlite3 *game_log_db = play_activity_db_open(); + + stmt = play_activity_db_prepare(game_log_db, sql); + + int play_activity_count = 0; + while (sqlite3_step(stmt) == SQLITE_ROW) { + play_activity_count++; + } + sqlite3_reset(stmt); + + play_activities = (PlayActivities *)malloc(sizeof(PlayActivities)); + play_activities->count = play_activity_count; + play_activities->play_time_total = 0; + play_activities->play_activity = (PlayActivity **)malloc(sizeof(PlayActivity *) * play_activities->count); + + for (int i = 0; i < play_activities->count; i++) { + if (sqlite3_step(stmt) != SQLITE_ROW) + break; + + PlayActivity *entry = play_activities->play_activity[i] = (PlayActivity *)malloc(sizeof(PlayActivity)); + ROM *rom = play_activities->play_activity[i]->rom = (ROM *)malloc(sizeof(ROM)); + entry->first_played_at = NULL; + entry->last_played_at = NULL; + + rom->id = sqlite3_column_int(stmt, 0); + rom->type = strdup((const char *)sqlite3_column_text(stmt, 1)); + rom->name = strdup((const char *)sqlite3_column_text(stmt, 2)); + if (sqlite3_column_text(stmt, 3) != NULL) { + rom->file_path = strdup((const char *)sqlite3_column_text(stmt, 3)); + rom->image_path = malloc(STR_MAX * sizeof(char)); + memset(rom->image_path, 0, STR_MAX); + get_rom_image_path(rom->file_path, rom->image_path); + } + + entry->play_count = sqlite3_column_int(stmt, 4); + entry->play_time_total = sqlite3_column_int(stmt, 5); + entry->play_time_average = sqlite3_column_int(stmt, 6); + if (sqlite3_column_text(stmt, 8) != NULL) { + entry->first_played_at = strdup((const char *)sqlite3_column_text(stmt, 7)); + } + if (sqlite3_column_text(stmt, 9) != NULL) { + entry->last_played_at = strdup((const char *)sqlite3_column_text(stmt, 8)); + } + + play_activities->play_time_total += entry->play_time_total; + } + + sqlite3_finalize(stmt); + play_activity_db_close(game_log_db); + + return play_activities; } void __ensure_rel_path(char *rel_path, const char *rom_path) { - if (!pathRelativeTo(rel_path, ROMS_PATH, rom_path)) { - if (strstr(rom_path, "../../Roms/") != NULL) { - strcpy(rel_path, splitString(strdup((const char *)rom_path), "../../Roms/")); - } - else { - strcpy(rel_path, replaceString2(strdup((const char *)rom_path), ROMS_PATH "/", "")); - } - } + if (!pathRelativeTo(rel_path, ROMS_PATH, rom_path)) { + if (strstr(rom_path, "../../Roms/") != NULL) { + strcpy(rel_path, splitString(strdup((const char *)rom_path), "../../Roms/")); + } else { + strcpy(rel_path, replaceString2(strdup((const char *)rom_path), ROMS_PATH "/", "")); + } + } } -int __db_insert_rom(sqlite3* game_log_db, const char *rom_type, const char *rom_name, const char *file_path, const char *image_path) +int __db_insert_rom(sqlite3 *game_log_db, const char *rom_type, const char *rom_name, const char *file_path, + const char *image_path) { - int rom_id = ROM_NOT_FOUND; + int rom_id = ROM_NOT_FOUND; - char rel_path[MAX_PATH]; - __ensure_rel_path(rel_path, file_path); + char rel_path[MAX_PATH]; + __ensure_rel_path(rel_path, file_path); - char *sql = sqlite3_mprintf("INSERT INTO rom(type, name, file_path, image_path) VALUES(%Q, %Q, %Q, %Q);", - rom_type, rom_name, rel_path, image_path); - sqlite3_exec(game_log_db, sql, NULL, NULL, NULL); - sqlite3_free(sql); + char *sql = sqlite3_mprintf("INSERT INTO rom(type, name, file_path, image_path) VALUES(%Q, %Q, %Q, %Q);", rom_type, + rom_name, rel_path, image_path); + sqlite3_exec(game_log_db, sql, NULL, NULL, NULL); + sqlite3_free(sql); - sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, "SELECT id FROM rom WHERE ROWID = last_insert_rowid()"); - if (sqlite3_step(stmt) == SQLITE_ROW) { - rom_id = sqlite3_column_int(stmt, 0); - } - sqlite3_finalize(stmt); + sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, "SELECT id FROM rom WHERE ROWID = last_insert_rowid()"); + if (sqlite3_step(stmt) == SQLITE_ROW) { + rom_id = sqlite3_column_int(stmt, 0); + } + sqlite3_finalize(stmt); - return rom_id; + return rom_id; } -void __db_update_rom(sqlite3* game_log_db, int rom_id, const char *rom_type, const char *rom_name, const char *file_path, const char *image_path) +void __db_update_rom(sqlite3 *game_log_db, int rom_id, const char *rom_type, const char *rom_name, + const char *file_path, const char *image_path) { - char rel_path[MAX_PATH]; - __ensure_rel_path(rel_path, file_path); + char rel_path[MAX_PATH]; + __ensure_rel_path(rel_path, file_path); - char *sql = sqlite3_mprintf("UPDATE rom SET type = %Q, name = %Q, file_path = %Q, image_path = %Q WHERE id = %d;", - rom_type, rom_name, rel_path, image_path, rom_id); - sqlite3_exec(game_log_db, sql, NULL, NULL, NULL); - sqlite3_free(sql); + char *sql = sqlite3_mprintf("UPDATE rom SET type = %Q, name = %Q, file_path = %Q, image_path = %Q WHERE id = %d;", + rom_type, rom_name, rel_path, image_path, rom_id); + sqlite3_exec(game_log_db, sql, NULL, NULL, NULL); + sqlite3_free(sql); } -int __db_get_orphan_rom_id(sqlite3* game_log_db, const char *rom_path) +int __db_get_orphan_rom_id(sqlite3 *game_log_db, const char *rom_path) { - int rom_id = ROM_NOT_FOUND; - char *_file_name = strdup(rom_path); - const char *file_name = baseName(_file_name); - char *rom_name = removeExtension(file_name); + int rom_id = ROM_NOT_FOUND; + char *_file_name = strdup(rom_path); + const char *file_name = baseName(_file_name); + char *rom_name = removeExtension(file_name); - char *sql = sqlite3_mprintf("SELECT id FROM rom WHERE (name=%Q OR name=%Q) AND type='ORPHAN' LIMIT 1;", rom_name, file_name); - sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); - sqlite3_free(sql); - free(rom_name); - free(_file_name); + char *sql = sqlite3_mprintf("SELECT id FROM rom WHERE (name=%Q OR name=%Q) AND type='ORPHAN' LIMIT 1;", rom_name, + file_name); + sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); + sqlite3_free(sql); + free(rom_name); + free(_file_name); - if (sqlite3_step(stmt) == SQLITE_ROW) { - rom_id = sqlite3_column_int(stmt, 0); - } + if (sqlite3_step(stmt) == SQLITE_ROW) { + rom_id = sqlite3_column_int(stmt, 0); + } - sqlite3_finalize(stmt); + sqlite3_finalize(stmt); - return rom_id; + return rom_id; } -int __db_get_rom_id_by_path(sqlite3* game_log_db, const char *rom_path) +int __db_get_rom_id_by_path(sqlite3 *game_log_db, const char *rom_path) { - int rom_id = ROM_NOT_FOUND; + int rom_id = ROM_NOT_FOUND; - char rel_path[MAX_PATH]; - __ensure_rel_path(rel_path, rom_path); + char rel_path[MAX_PATH]; + __ensure_rel_path(rel_path, rom_path); - char *sql = sqlite3_mprintf("SELECT id FROM rom WHERE file_path=%Q LIMIT 1;", rel_path); - sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); - sqlite3_free(sql); + char *sql = sqlite3_mprintf("SELECT id FROM rom WHERE file_path=%Q LIMIT 1;", rel_path); + sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); + sqlite3_free(sql); - if (sqlite3_step(stmt) == SQLITE_ROW) { - rom_id = sqlite3_column_int(stmt, 0); - } + if (sqlite3_step(stmt) == SQLITE_ROW) { + rom_id = sqlite3_column_int(stmt, 0); + } - sqlite3_finalize(stmt); + sqlite3_finalize(stmt); - return rom_id; + return rom_id; } -int __db_rom_find_by_file_path(sqlite3* game_log_db, const char *rom_path, bool create_or_update) +int __db_rom_find_by_file_path(sqlite3 *game_log_db, const char *rom_path, bool create_or_update) { - //LOG_info("rom_find_by_file_path('%s')\n", rom_path); - - bool update_orphan = false; - int rom_id = __db_get_rom_id_by_path(game_log_db, rom_path); - - if (rom_id == ROM_NOT_FOUND) { - rom_id = __db_get_orphan_rom_id(game_log_db, rom_path); - if (rom_id != ROM_NOT_FOUND) { - update_orphan = true; - } - } - - if (update_orphan) { - char *rom_name = removeExtension(baseName(rom_path)); - __db_update_rom(game_log_db, rom_id, "", rom_name, rom_path, ""); - free(rom_name); - } - else if (rom_id == ROM_NOT_FOUND && create_or_update) { - char *rom_name = removeExtension(baseName(rom_path)); - rom_id = __db_insert_rom(game_log_db, "", rom_name, rom_path, ""); - free(rom_name); - } - - return rom_id; + // LOG_info("rom_find_by_file_path('%s')\n", rom_path); + + bool update_orphan = false; + int rom_id = __db_get_rom_id_by_path(game_log_db, rom_path); + + if (rom_id == ROM_NOT_FOUND) { + rom_id = __db_get_orphan_rom_id(game_log_db, rom_path); + if (rom_id != ROM_NOT_FOUND) { + update_orphan = true; + } + } + + if (update_orphan) { + char *rom_name = removeExtension(baseName(rom_path)); + __db_update_rom(game_log_db, rom_id, "", rom_name, rom_path, ""); + free(rom_name); + } else if (rom_id == ROM_NOT_FOUND && create_or_update) { + char *rom_name = removeExtension(baseName(rom_path)); + rom_id = __db_insert_rom(game_log_db, "", rom_name, rom_path, ""); + free(rom_name); + } + + return rom_id; } int play_activity_transaction_rom_find_by_file_path(const char *rom_path, bool create_or_update) { - int retval; - sqlite3* game_log_db = play_activity_db_open(); - retval = __db_rom_find_by_file_path(game_log_db, rom_path, create_or_update); - play_activity_db_close(game_log_db); - return retval; + int retval; + sqlite3 *game_log_db = play_activity_db_open(); + retval = __db_rom_find_by_file_path(game_log_db, rom_path, create_or_update); + play_activity_db_close(game_log_db); + return retval; } int play_activity_get_play_time(const char *rom_path) { - int play_time = 0; - sqlite3* game_log_db = play_activity_db_open(); - int rom_id = __db_rom_find_by_file_path(game_log_db, rom_path, false); - if (rom_id != ROM_NOT_FOUND) { - char *sql = sqlite3_mprintf("SELECT SUM(play_time) FROM play_activity WHERE rom_id = %d;", rom_id); - sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); - sqlite3_free(sql); - if (sqlite3_step(stmt) == SQLITE_ROW) { - play_time = sqlite3_column_int(stmt, 0); - } - sqlite3_finalize(stmt); - } - play_activity_db_close(game_log_db); - return play_time; + int play_time = 0; + sqlite3 *game_log_db = play_activity_db_open(); + int rom_id = __db_rom_find_by_file_path(game_log_db, rom_path, false); + if (rom_id != ROM_NOT_FOUND) { + char *sql = sqlite3_mprintf("SELECT SUM(play_time) FROM play_activity WHERE rom_id = %d;", rom_id); + sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); + sqlite3_free(sql); + if (sqlite3_step(stmt) == SQLITE_ROW) { + play_time = sqlite3_column_int(stmt, 0); + } + sqlite3_finalize(stmt); + } + play_activity_db_close(game_log_db); + return play_time; } bool _get_active_rom_path(char *rom_path_out) { - char *ptr; - char cmd[STR_MAX]; - getFile(CMD_TO_RUN, cmd, STR_MAX); - trimTrailingNewlines(cmd); - - if (strlen(cmd) == 0) { - return false; - } - - if ((ptr = strrchr(cmd, '\'')) != NULL) { - *ptr = '\0'; - } - - if ((ptr = strrchr(cmd, '\'')) != NULL) { - strncpy(rom_path_out, ptr + 1, STR_MAX); - return true; - } - return false; + char *ptr; + char cmd[STR_MAX]; + getFile(CMD_TO_RUN, cmd, STR_MAX); + trimTrailingNewlines(cmd); + + if (strlen(cmd) == 0) { + return false; + } + + if ((ptr = strrchr(cmd, '\'')) != NULL) { + *ptr = '\0'; + } + + if ((ptr = strrchr(cmd, '\'')) != NULL) { + strncpy(rom_path_out, ptr + 1, STR_MAX); + return true; + } + return false; } -int __db_get_active_closed_activity(sqlite3* game_log_db) +int __db_get_active_closed_activity(sqlite3 *game_log_db) { - int rom_id = ROM_NOT_FOUND; + int rom_id = ROM_NOT_FOUND; - char rom_path[STR_MAX]; - if (!_get_active_rom_path(rom_path)) { - return ROM_NOT_FOUND; - } + char rom_path[STR_MAX]; + if (!_get_active_rom_path(rom_path)) { + return ROM_NOT_FOUND; + } - //printf("Last closed active rom: %s\n", rom_path); + // printf("Last closed active rom: %s\n", rom_path); - if ((rom_id = __db_rom_find_by_file_path(game_log_db, rom_path, false)) == ROM_NOT_FOUND) { - return ROM_NOT_FOUND; - } + if ((rom_id = __db_rom_find_by_file_path(game_log_db, rom_path, false)) == ROM_NOT_FOUND) { + return ROM_NOT_FOUND; + } - char *sql = sqlite3_mprintf("SELECT * FROM play_activity WHERE rom_id = %d AND play_time IS NULL;", rom_id); - sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); + char *sql = sqlite3_mprintf("SELECT * FROM play_activity WHERE rom_id = %d AND play_time IS NULL;", rom_id); + sqlite3_stmt *stmt = play_activity_db_prepare(game_log_db, sql); - if (sqlite3_step(stmt) == SQLITE_ROW) { - // Activity is not closed - rom_id = ROM_NOT_FOUND; - } + if (sqlite3_step(stmt) == SQLITE_ROW) { + // Activity is not closed + rom_id = ROM_NOT_FOUND; + } - sqlite3_free(sql); - sqlite3_finalize(stmt); + sqlite3_free(sql); + sqlite3_finalize(stmt); - return rom_id; + return rom_id; } void play_activity_start(char *rom_file_path) { - //LOG_info("\n:: play_activity_start(%s)\n", rom_file_path); - int rom_id = play_activity_transaction_rom_find_by_file_path(rom_file_path, true); - if (rom_id == ROM_NOT_FOUND) { - exit(1); - } - char *sql = sqlite3_mprintf("INSERT INTO play_activity(rom_id) VALUES(%d);", rom_id); - play_activity_db_execute(sql); - sqlite3_free(sql); + // LOG_info("\n:: play_activity_start(%s)\n", rom_file_path); + int rom_id = play_activity_transaction_rom_find_by_file_path(rom_file_path, true); + if (rom_id == ROM_NOT_FOUND) { + exit(1); + } + char *sql = sqlite3_mprintf("INSERT INTO play_activity(rom_id) VALUES(%d);", rom_id); + play_activity_db_execute(sql); + sqlite3_free(sql); } void play_activity_resume(void) { - //LOG_info("\n:: play_activity_resume()"); - sqlite3* game_log_db = play_activity_db_open(); - int rom_id = play_activity_db_transaction(game_log_db, __db_get_active_closed_activity); - play_activity_db_close(game_log_db); - if (rom_id == ROM_NOT_FOUND) { - printf("Error: no active rom\n"); - exit(1); - } - char *sql = sqlite3_mprintf("INSERT INTO play_activity(rom_id) VALUES(%d);", rom_id); - play_activity_db_execute(sql); - sqlite3_free(sql); + // LOG_info("\n:: play_activity_resume()"); + sqlite3 *game_log_db = play_activity_db_open(); + int rom_id = play_activity_db_transaction(game_log_db, __db_get_active_closed_activity); + play_activity_db_close(game_log_db); + if (rom_id == ROM_NOT_FOUND) { + printf("Error: no active rom\n"); + exit(1); + } + char *sql = sqlite3_mprintf("INSERT INTO play_activity(rom_id) VALUES(%d);", rom_id); + play_activity_db_execute(sql); + sqlite3_free(sql); } void play_activity_stop(char *rom_file_path) { - //LOG_info("\n:: play_activity_stop(%s)\n", rom_file_path); - int rom_id = play_activity_transaction_rom_find_by_file_path(rom_file_path, false); - if (rom_id == ROM_NOT_FOUND) { - exit(1); - } - char *sql = sqlite3_mprintf("UPDATE play_activity SET play_time = (strftime('%%s', 'now')) - created_at, updated_at = (strftime('%%s', 'now')) WHERE rom_id = %d AND play_time IS NULL;", rom_id); - play_activity_db_execute(sql); - sqlite3_free(sql); + // LOG_info("\n:: play_activity_stop(%s)\n", rom_file_path); + int rom_id = play_activity_transaction_rom_find_by_file_path(rom_file_path, false); + if (rom_id == ROM_NOT_FOUND) { + exit(1); + } + char *sql = sqlite3_mprintf("UPDATE play_activity SET play_time = (strftime('%%s', 'now')) - created_at, " + "updated_at = (strftime('%%s', 'now')) WHERE rom_id = %d AND play_time IS NULL;", + rom_id); + play_activity_db_execute(sql); + sqlite3_free(sql); } void play_activity_stop_all(void) { - //LOG_info("\n:: play_activity_stop_all()"); - play_activity_db_execute( - "UPDATE play_activity SET play_time = (strftime('%s', 'now')) - created_at, updated_at = (strftime('%s', 'now')) WHERE play_time IS NULL;" - "DELETE FROM play_activity WHERE play_time < 0;"); + // LOG_info("\n:: play_activity_stop_all()"); + play_activity_db_execute("UPDATE play_activity SET play_time = (strftime('%s', 'now')) - created_at, updated_at = " + "(strftime('%s', 'now')) WHERE play_time IS NULL;" + "DELETE FROM play_activity WHERE play_time < 0;"); } void play_activity_list_all(void) { - //LOG_info("\n:: play_activity_list_all()"); - int total_play_time = play_activity_get_total_play_time(); - PlayActivities *pas = play_activity_find_all(); - - printf("\n"); - - for (int i = 0; i < pas->count; i++) { - PlayActivity *entry = pas->play_activity[i]; - ROM *rom = entry->rom; - char rom_name[STR_MAX]; - cleanName(rom_name, rom->name); - char play_time[STR_MAX]; - serializeTime(play_time, entry->play_time_total); - printf("%03d: %s (%s) [%s]\n", i + 1, rom_name, play_time, rom->type); - } - - char total_str[25]; - serializeTime(total_str, total_play_time); - printf("\nTotal: %s\n", total_str); - - free_play_activities(pas); + // LOG_info("\n:: play_activity_list_all()"); + int total_play_time = play_activity_get_total_play_time(); + PlayActivities *pas = play_activity_find_all(); + + printf("\n"); + + for (int i = 0; i < pas->count; i++) { + PlayActivity *entry = pas->play_activity[i]; + ROM *rom = entry->rom; + char rom_name[STR_MAX]; + cleanName(rom_name, rom->name); + char play_time[STR_MAX]; + serializeTime(play_time, entry->play_time_total); + printf("%03d: %s (%s) [%s]\n", i + 1, rom_name, play_time, rom->type); + } + + char total_str[25]; + serializeTime(total_str, total_play_time); + printf("\nTotal: %s\n", total_str); + + free_play_activities(pas); } \ No newline at end of file diff --git a/workspace/all/libgametimedb/gametimedb.h b/workspace/all/libgametimedb/gametimedb.h index 4c0e4eb1d..be626a37c 100644 --- a/workspace/all/libgametimedb/gametimedb.h +++ b/workspace/all/libgametimedb/gametimedb.h @@ -7,33 +7,33 @@ typedef struct PlayActivity PlayActivity; typedef struct PlayActivities PlayActivities; struct ROM { - int id; - char *type; - char *name; - char *file_path; - char *image_path; + int id; + char *type; + char *name; + char *file_path; + char *image_path; }; struct PlayActivity { - ROM *rom; - int play_count; - int play_time_total; - int play_time_average; - char *first_played_at; - char *last_played_at; + ROM *rom; + int play_count; + int play_time_total; + int play_time_average; + char *first_played_at; + char *last_played_at; }; struct PlayActivities { - PlayActivity **play_activity; - int count; - int play_time_total; + PlayActivity **play_activity; + int count; + int play_time_total; }; -sqlite3* play_activity_db_open(void); -void play_activity_db_close(sqlite3* ctx); +sqlite3 *play_activity_db_open(void); +void play_activity_db_close(sqlite3 *ctx); void free_play_activities(PlayActivities *pa_ptr); // Main interface functions for read access PlayActivities *play_activity_find_all(void); -//int play_activity_get_play_time(const char *rom_path); +// int play_activity_get_play_time(const char *rom_path); // Main interface functions for write access void play_activity_start(char *rom_file_path); diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index f1a63884c..72710c56c 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -31,7 +31,7 @@ /////////////////////////////////////// -static SDL_Surface* screen; +static SDL_Surface *screen; static int quit = 0; static int newScreenshot = 0; static int show_menu = 0; @@ -40,9 +40,9 @@ static int was_threaded = 0; static int should_run_core = 1; // used by threaded video enum retro_pixel_format fmt; -static pthread_t core_pt; -static pthread_mutex_t core_mx; -static pthread_cond_t core_rq; // not sure this is required +static pthread_t core_pt; +static pthread_mutex_t core_mx; +static pthread_cond_t core_rq; // not sure this is required enum { @@ -62,7 +62,7 @@ static int screen_sharpness = SHARPNESS_SOFT; static int screen_effect = EFFECT_NONE; static int screenx = 64; static int screeny = 64; -static int overlay = 0; +static int overlay = 0; static int prevent_tearing = 1; // lenient static int use_core_fps = 0; static int sync_ref = 0; @@ -73,11 +73,11 @@ static int fast_forward = 0; static int overclock = 3; // auto static int has_custom_controllers = 0; static int gamepad_type = 0; // index in gamepad_labels/gamepad_values -static int downsample = 0; // set to 1 to convert from 8888 to 565 +static int downsample = 0; // set to 1 to convert from 8888 to 565 // these are no longer constants as of the RG CubeXX (even though they look like it) -static int DEVICE_WIDTH = 0; // FIXED_WIDTH; +static int DEVICE_WIDTH = 0; // FIXED_WIDTH; static int DEVICE_HEIGHT = 0; // FIXED_HEIGHT; -static int DEVICE_PITCH = 0; // FIXED_PITCH; +static int DEVICE_PITCH = 0; // FIXED_PITCH; GFX_Renderer renderer; @@ -86,70 +86,71 @@ GFX_Renderer renderer; static struct Core { int initialized; int need_fullpath; - - const char tag[8]; // eg. GBC - const char name[128]; // eg. gambatte - const char version[128]; // eg. Gambatte (v0.5.0-netlink 7e02df6) + + const char tag[8]; // eg. GBC + const char name[128]; // eg. gambatte + const char version[128]; // eg. Gambatte (v0.5.0-netlink 7e02df6) const char extensions[128]; // eg. gb|gbc|dmg - - const char config_dir[MAX_PATH]; // eg. /mnt/sdcard/.userdata/rg35xx/GB-gambatte - const char states_dir[MAX_PATH]; // eg. /mnt/sdcard/.userdata/arm-480/GB-gambatte - const char saves_dir[MAX_PATH]; // eg. /mnt/sdcard/Saves/GB - const char bios_dir[MAX_PATH]; // eg. /mnt/sdcard/Bios/GB - const char cheats_dir[MAX_PATH]; // eg. /mnt/sdcard/Cheats/GB + + const char config_dir[MAX_PATH]; // eg. /mnt/sdcard/.userdata/rg35xx/GB-gambatte + const char states_dir[MAX_PATH]; // eg. /mnt/sdcard/.userdata/arm-480/GB-gambatte + const char saves_dir[MAX_PATH]; // eg. /mnt/sdcard/Saves/GB + const char bios_dir[MAX_PATH]; // eg. /mnt/sdcard/Bios/GB + const char cheats_dir[MAX_PATH]; // eg. /mnt/sdcard/Cheats/GB const char overlays_dir[MAX_PATH]; // eg. /mnt/sdcard/Cheats/GB - + double fps; double sample_rate; double aspect_ratio; - void* handle; + void *handle; void (*init)(void); void (*deinit)(void); - + void (*get_system_info)(struct retro_system_info *info); void (*get_system_av_info)(struct retro_system_av_info *info); void (*set_controller_port_device)(unsigned port, unsigned device); - + void (*reset)(void); void (*run)(void); size_t (*serialize_size)(void); bool (*serialize)(void *data, size_t size); bool (*unserialize)(const void *data, size_t size); void (*cheat_reset)(void); - void (*cheat_set)(unsigned id, bool enabled, const char*); + void (*cheat_set)(unsigned id, bool enabled, const char *); bool (*load_game)(const struct retro_game_info *game); bool (*load_game_special)(unsigned game_type, const struct retro_game_info *info, size_t num_info); void (*unload_game)(void); unsigned (*get_region)(void); void *(*get_memory_data)(unsigned id); size_t (*get_memory_size)(unsigned id); - + retro_core_options_update_display_callback_t update_visibility_callback; // retro_audio_buffer_status_callback_t audio_buffer_status; } core; -int extract_zip(char** extensions); -static bool getAlias(char* path, char* alias); +int extract_zip(char **extensions); +static bool getAlias(char *path, char *alias); static struct Game { char path[MAX_PATH]; - char name[MAX_PATH]; // TODO: rename to basename? + char name[MAX_PATH]; // TODO: rename to basename? char alt_name[MAX_PATH]; // alternate name, eg. unzipped rom file name char m3u_path[MAX_PATH]; char tmp_path[MAX_PATH]; // location of unzipped file - void* data; + void *data; size_t size; int is_open; } game; -static void Game_open(char* path) { +static void Game_open(char *path) +{ LOG_info("Game_open\n"); int skipzip = 0; memset(&game, 0, sizeof(game)); - - strcpy((char*)game.path, path); - strcpy((char*)game.name, strrchr(path, '/')+1); - strcpy((char*)game.alt_name, game.name); // default it + + strcpy((char *)game.path, path); + strcpy((char *)game.name, strrchr(path, '/') + 1); + strcpy((char *)game.alt_name, game.name); // default it // check first if the rom already is alive in tmp folder if so skip unzipping shit char tmpfldr[255]; @@ -157,26 +158,26 @@ static void Game_open(char* path) { char *tmppath = PLAT_findFileInDir(tmpfldr, game.name); if (tmppath) { printf("File exists skipping unzipping and setting game.tmp_path: %s\n", tmppath); - strcpy((char*)game.tmp_path, tmppath); + strcpy((char *)game.tmp_path, tmppath); skipzip = 1; free(tmppath); // Update the game name to the extracted file name instead of the zip name if (CFG_getUseExtractedFileName()) - strcpy((char*)game.alt_name, strrchr(game.tmp_path, '/')+1); + strcpy((char *)game.alt_name, strrchr(game.tmp_path, '/') + 1); } else { - printf("File does not exist in %s\n",tmpfldr); + printf("File does not exist in %s\n", tmpfldr); } - + // if we have a zip file if (suffixMatch(".zip", game.path) && !skipzip) { LOG_info("is zip file\n"); int supports_zip = 0; int i = 0; - char* ext; + char *ext; char exts[128]; - char* extensions[32]; - strcpy(exts,core.extensions); - while ((ext=strtok(i?NULL:exts,"|"))) { + char *extensions[32]; + strcpy(exts, core.extensions); + while ((ext = strtok(i ? NULL : exts, "|"))) { extensions[i++] = ext; if (!strcmp("zip", ext)) { supports_zip = 1; @@ -184,51 +185,50 @@ static void Game_open(char* path) { } } extensions[i] = NULL; - + // if the core doesn't support zip files natively if (!supports_zip) { // extract zip file located at game.path to game.tmp_path // game.tmp_path is temp dir generated by mkdtemp LOG_info("Extracting zip file manually: %s\n", game.path); - if(!extract_zip(extensions)) + if (!extract_zip(extensions)) return; // Update the game name to the extracted file name instead of the zip name if (CFG_getUseExtractedFileName()) - strcpy((char*)game.alt_name, strrchr(game.tmp_path, '/')+1); - } - else { + strcpy((char *)game.alt_name, strrchr(game.tmp_path, '/') + 1); + } else { LOG_info("Core can handle zip file: %s\n", game.path); } } - + // some cores handle opening files themselves, eg. pcsx_rearmed // if the frontend tries to load a 500MB file itself bad things happen if (!core.need_fullpath) { - path = game.tmp_path[0]=='\0'?game.path:game.tmp_path; + path = game.tmp_path[0] == '\0' ? game.path : game.tmp_path; FILE *file = fopen(path, "r"); - if (file==NULL) { + if (file == NULL) { LOG_error("Error opening game: %s\n\t%s\n", path, strerror(errno)); return; } - + fseek(file, 0, SEEK_END); game.size = ftell(file); - + rewind(file); game.data = malloc(game.size); - if (game.data==NULL) { + if (game.data == NULL) { LOG_error("Couldn't allocate memory for file: %s\n", path); return; } - + fread(game.data, sizeof(uint8_t), game.size, file); - + fclose(file); } - + // m3u-based? - char* tmp; + char *tmp; char m3u_path[256]; char base_path[256]; char dir_name[256]; @@ -236,31 +236,33 @@ static void Game_open(char* path) { strcpy(m3u_path, game.path); tmp = strrchr(m3u_path, '/') + 1; tmp[0] = '\0'; - + strcpy(base_path, m3u_path); - + tmp = strrchr(m3u_path, '/'); tmp[0] = '\0'; tmp = strrchr(m3u_path, '/'); strcpy(dir_name, tmp); - - tmp = m3u_path + strlen(m3u_path); + + tmp = m3u_path + strlen(m3u_path); strcpy(tmp, dir_name); - + tmp = m3u_path + strlen(m3u_path); strcpy(tmp, ".m3u"); - + if (exists(m3u_path)) { strcpy(game.m3u_path, m3u_path); - strcpy((char*)game.name, strrchr(m3u_path, '/')+1); - strcpy((char*)game.alt_name, game.name); // default it + strcpy((char *)game.name, strrchr(m3u_path, '/') + 1); + strcpy((char *)game.alt_name, game.name); // default it } - + game.is_open = 1; } -static void Game_close(void) { - if (game.data) free(game.data); +static void Game_close(void) +{ + if (game.data) + free(game.data); // why delete tempfile? keep it for next time when loading the game its much faster from /tmp ram folder // if (game.tmp_path[0]) remove(game.tmp_path); game.is_open = 0; @@ -268,23 +270,24 @@ static void Game_close(void) { } static struct retro_disk_control_ext_callback disk_control_ext; -static void Game_changeDisc(char* path) { - - if (exactMatch(game.path, path) || !exists(path)) return; - +static void Game_changeDisc(char *path) +{ + if (exactMatch(game.path, path) || !exists(path)) + return; + Game_close(); Game_open(path); - + struct retro_game_info game_info = {}; game_info.path = game.path; game_info.data = game.data; game_info.size = game.size; - + disk_control_ext.replace_image_index(0, &game_info); putFile(CHANGE_DISC_PATH, path); // NextUI still needs to know this to update recents.txt } -int extract_zip(char** extensions) +int extract_zip(char **extensions) { char buf[100]; struct zip *za; @@ -298,11 +301,11 @@ int extract_zip(char** extensions) // char tmp_template[MAX_PATH]; // strcpy(tmp_template, "/tmp/minarch-XXXXXX"); - - mkdir("/tmp/nextarch",0777); + + mkdir("/tmp/nextarch", 0777); char tmp_dirname[255]; - snprintf(tmp_dirname, sizeof(tmp_dirname), "%s/%s", "/tmp/nextarch",core.tag); - mkdir(tmp_dirname,0777); + snprintf(tmp_dirname, sizeof(tmp_dirname), "%s/%s", "/tmp/nextarch", core.tag); + mkdir(tmp_dirname, 0777); int i, len; int fd; @@ -312,43 +315,44 @@ int extract_zip(char** extensions) for (i = 0; i < zip_get_num_entries(za, 0); i++) { if (zip_stat_index(za, i, 0, &sb) == 0) { len = strlen(sb.name); - //LOG_info("Name: [%s], ", sb.name); - //LOG_info("Size: [%llu], ", sb.size); - //LOG_info("mtime: [%u]\n", (unsigned int)sb.mtime); + // LOG_info("Name: [%s], ", sb.name); + // LOG_info("Size: [%llu], ", sb.size); + // LOG_info("mtime: [%u]\n", (unsigned int)sb.mtime); if (sb.name[len - 1] == '/') { - sprintf(game.tmp_path, "%s/%s", tmp_dirname, basename((char*)sb.name)); + sprintf(game.tmp_path, "%s/%s", tmp_dirname, basename((char *)sb.name)); } else { int found = 0; char extension[8]; - for (int e=0; extensions[e]; e++) { + for (int e = 0; extensions[e]; e++) { sprintf(extension, ".%s", extensions[e]); if (suffixMatch(extension, sb.name)) { found = 1; break; } } - if (!found) continue; + if (!found) + continue; zf = zip_fopen_index(za, i, 0); if (!zf) { - LOG_error( "zip_fopen_index failed\n"); + LOG_error("zip_fopen_index failed\n"); return 0; } - sprintf(game.tmp_path, "%s/%s", tmp_dirname, basename((char*)sb.name)); + sprintf(game.tmp_path, "%s/%s", tmp_dirname, basename((char *)sb.name)); fd = open(game.tmp_path, O_RDWR | O_TRUNC | O_CREAT, 0644); if (fd < 0) { - LOG_error( "open failed\n"); + LOG_error("open failed\n"); zip_fclose(zf); return 0; } - //LOG_info("Writing: %s\n", game.tmp_path); + // LOG_info("Writing: %s\n", game.tmp_path); sum = 0; while (sum != sb.size) { len = zip_fread(zf, buf, 100); if (len < 0) { - LOG_error( "zip_fread failed\n"); + LOG_error("zip_fread failed\n"); close(fd); zip_fclose(zf); return 0; @@ -362,7 +366,7 @@ int extract_zip(char** extensions) } } } - + if (zip_close(za) == -1) { LOG_error("can't close zip archive `%s'\n", game.path); return 0; @@ -391,30 +395,33 @@ static struct Cheats { #define CHEAT_MAX_LINE_LEN 52 #define CHEAT_MAX_LINES 3 -static size_t parse_count(FILE *file) { +static size_t parse_count(FILE *file) +{ size_t count = 0; fscanf(file, " cheats = %lu\n", (unsigned long *)&count); return count; } -static const char *find_val(const char *start) { +static const char *find_val(const char *start) +{ start--; - while(!isspace(*++start)) + while (!isspace(*++start)) ; - while(isspace(*++start)) + while (isspace(*++start)) ; if (*start != '=') return NULL; - while(isspace(*++start)) + while (isspace(*++start)) ; return start; } -static int parse_bool(const char *ptr, int *out) { +static int parse_bool(const char *ptr, int *out) +{ if (!strncasecmp(ptr, "true", 4)) { *out = 1; } else if (!strncasecmp(ptr, "false", 5)) { @@ -425,7 +432,8 @@ static int parse_bool(const char *ptr, int *out) { return 0; } -static int parse_string(const char *ptr, char *buf, size_t len) { +static int parse_string(const char *ptr, char *buf, size_t len) +{ int index = 0; size_t input_len = strlen(ptr); @@ -455,7 +463,8 @@ static int parse_string(const char *ptr, char *buf, size_t len) { return 0; } -static int parse_cheats(struct Cheats *cheats, FILE *file) { +static int parse_cheats(struct Cheats *cheats, FILE *file) +{ int ret = -1; char line[512]; char buf[512]; @@ -493,7 +502,7 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { if (len == 0) continue; - cheat->name = calloc(len+1, sizeof(char)); + cheat->name = calloc(len + 1, sizeof(char)); if (!cheat->name) goto finish; @@ -501,7 +510,7 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { truncateString((char *)cheat->name, CHEAT_MAX_DESC_LEN); if (len >= CHEAT_MAX_DESC_LEN) { - cheat->info = calloc(len+1, sizeof(char)); + cheat->info = calloc(len + 1, sizeof(char)); if (!cheat->info) goto finish; @@ -519,7 +528,7 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { if (len == 0) continue; - cheat->code = calloc(len+1, sizeof(char)); + cheat->code = calloc(len + 1, sizeof(char)); if (!cheat->code) goto finish; @@ -532,7 +541,7 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { } } } - } while(1); + } while (1); finish: return ret; @@ -541,26 +550,30 @@ static int parse_cheats(struct Cheats *cheats, FILE *file) { // return variations with/without extensions and other cruft #define CHEAT_MAX_PATHS 16 #define CHEAT_MAX_LIST_LENGTH (CHEAT_MAX_PATHS * MAX_PATH) -static void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { +static void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int *count) +{ // Generate possible paths, ordered by most likely to be used (pre v6.2.3 style first) - sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, game.name); // /mnt/SDCARD/Cheats/GB/Super Example World..cht - if(CFG_getUseExtractedFileName()) - sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, game.alt_name); // /mnt/SDCARD/Cheats/GB/Super Example World (USA)..cht + sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, + game.name); // /mnt/SDCARD/Cheats/GB/Super Example World..cht + if (CFG_getUseExtractedFileName()) + sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, + game.alt_name); // /mnt/SDCARD/Cheats/GB/Super Example World (USA)..cht // game.alt_name, but with all extension-like stuff removed (apart from .cht) // eg. Super Example World (USA).zip -> Super Example World (USA).cht { int i = 0; - char* ext; + char *ext; char exts[128]; - strcpy(exts,core.extensions); - while ((ext=strtok(i?NULL:exts,"|"))) { + strcpy(exts, core.extensions); + while ((ext = strtok(i ? NULL : exts, "|"))) { char rom_name[MAX_PATH]; strcpy(rom_name, game.alt_name); - char* tmp = strrchr(rom_name, '.'); + char *tmp = strrchr(rom_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; - sprintf(paths[(*count)++], "%s/%s.%s.cht", core.cheats_dir, rom_name, ext); // /mnt/SDCARD/Cheats/GB/Super Example World (USA).foo.cht + sprintf(paths[(*count)++], "%s/%s.%s.cht", core.cheats_dir, rom_name, + ext); // /mnt/SDCARD/Cheats/GB/Super Example World (USA).foo.cht } i++; } @@ -576,28 +589,32 @@ static void Cheat_getPaths(char paths[CHEAT_MAX_PATHS][MAX_PATH], int* count) { // Respect map.txt: use alias if available // eg. 1941.zip -> 1941: Counter Attack - if(getAlias(game.path, rom_name)) - sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World.cht + if (getAlias(game.path, rom_name)) + sprintf(paths[(*count)++], "%s/%s.cht", core.cheats_dir, + rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World.cht // Santitized alias, ignoring all extra cruft - including Cheat specifics like "(Game Breaker)" etc. // This is a wildcard that may match something unexpected, but also may find something when nothing else does. getDisplayName(game.alt_name, rom_name); getAlias(game.path, rom_name); - sprintf(paths[(*count)++], "%s/%s*.cht", core.cheats_dir, rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World*.cht + sprintf(paths[(*count)++], "%s/%s*.cht", core.cheats_dir, + rom_name); // /mnt/SDCARD/Cheats/GB/Super Example World*.cht // Log all path candidates { int i; char list[CHEAT_MAX_LIST_LENGTH] = {0}; - for (i=0; i<*count; i++) { + for (i = 0; i < *count; i++) { strcat(list, paths[i]); - if (i < *count-1) strcat(list, ", "); + if (i < *count - 1) + strcat(list, ", "); } LOG_info("Cheat paths to check: %s\n", list); } } -void Cheats_free() { +void Cheats_free() +{ size_t i; for (i = 0; i < cheatcodes.count; i++) { struct Cheat *cheat = &cheatcodes.cheats[i]; @@ -611,7 +628,8 @@ void Cheats_free() { cheatcodes.count = 0; } -bool Cheats_load() { +bool Cheats_load() +{ int success = 0; struct Cheats *cheats = &cheatcodes; FILE *file = NULL; @@ -622,10 +640,10 @@ bool Cheats_load() { int path_count = 0; Cheat_getPaths(paths, &path_count); char filename[MAX_PATH] = {0}; - for (i=0; i 0) { for (size_t gi = 0; gi < glob_results.gl_pathc; ++gi) { - if (!suffixMatch(".cht", glob_results.gl_pathv[gi])) continue; + if (!suffixMatch(".cht", glob_results.gl_pathv[gi])) + continue; strcpy(filename, glob_results.gl_pathv[gi]); if (exists(filename)) { LOG_info("Found potential cheat file: %s\n", filename); @@ -646,7 +665,8 @@ bool Cheats_load() { } } globfree(&glob_results); - if (filename[0] == '\0') continue; // no match + if (filename[0] == '\0') + continue; // no match } else { strcpy(filename, paths[i]); if (!exists(filename)) { @@ -699,68 +719,72 @@ bool Cheats_load() { } /////////////////////////////////////// -static void formatSavePath(char* work_name, char* filename, const char* suffix) { - char* tmp = strrchr(work_name, '.'); +static void formatSavePath(char *work_name, char *filename, const char *suffix) +{ + char *tmp = strrchr(work_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; } sprintf(filename, "%s/%s%s", core.saves_dir, work_name, suffix); } -static void SRAM_getPath(char* filename) { +static void SRAM_getPath(char *filename) +{ char work_name[MAX_PATH]; - if (CFG_getSaveFormat() == SAVE_FORMAT_SRM - || CFG_getSaveFormat() == SAVE_FORMAT_SRM_UNCOMPRESSED) { + if (CFG_getSaveFormat() == SAVE_FORMAT_SRM || CFG_getSaveFormat() == SAVE_FORMAT_SRM_UNCOMPRESSED) { strcpy(work_name, game.alt_name); formatSavePath(work_name, filename, ".srm"); - } - else if (CFG_getSaveFormat() == SAVE_FORMAT_GEN) { + } else if (CFG_getSaveFormat() == SAVE_FORMAT_GEN) { strcpy(work_name, game.alt_name); formatSavePath(work_name, filename, ".sav"); - } - else { + } else { sprintf(filename, "%s/%s.sav", core.saves_dir, game.alt_name); } LOG_info("SRAM_getPath %s\n", filename); } -static void SRAM_read(void) { +static void SRAM_read(void) +{ size_t sram_size = core.get_memory_size(RETRO_MEMORY_SAVE_RAM); - if (!sram_size) return; - + if (!sram_size) + return; + char filename[MAX_PATH]; SRAM_getPath(filename); printf("sav path (read): %s\n", filename); - void* sram = core.get_memory_data(RETRO_MEMORY_SAVE_RAM); + void *sram = core.get_memory_data(RETRO_MEMORY_SAVE_RAM); #ifdef HAS_SRM // TODO: rzipstream_open can also handle uncompressed, else branch is probably unnecessary // srm, potentially compressed if (CFG_getSaveFormat() == SAVE_FORMAT_SRM) { - rzipstream_t* sram_file = rzipstream_open(filename, RETRO_VFS_FILE_ACCESS_READ); - if(!sram_file) return; + rzipstream_t *sram_file = rzipstream_open(filename, RETRO_VFS_FILE_ACCESS_READ); + if (!sram_file) + return; if (!sram || rzipstream_read(sram_file, sram, sram_size) < 0) LOG_error("rzipstream: Error reading SRAM data\n"); - + rzipstream_close(sram_file); } // uncompressed else { - RFILE* sram_file = filestream_open(filename, RETRO_VFS_FILE_ACCESS_READ, 0); - if(!sram_file) return; + RFILE *sram_file = filestream_open(filename, RETRO_VFS_FILE_ACCESS_READ, 0); + if (!sram_file) + return; if (!sram || filestream_read(sram_file, sram, sram_size) < 0) LOG_error("filestream: Error reading SRAM data\n"); - + filestream_close(sram_file); } -#else +#else FILE *sram_file = fopen(filename, "r"); - if (!sram_file) return; + if (!sram_file) + return; if (!sram || !fread(sram, 1, sram_size, sram_file)) { LOG_error("Error reading SRAM data\n"); } @@ -768,24 +792,25 @@ static void SRAM_read(void) { #endif } -static void SRAM_write(void) { +static void SRAM_write(void) +{ size_t sram_size = core.get_memory_size(RETRO_MEMORY_SAVE_RAM); - if (!sram_size) return; - + if (!sram_size) + return; + char filename[MAX_PATH]; SRAM_getPath(filename); printf("sav path (write): %s\n", filename); - + void *sram = core.get_memory_data(RETRO_MEMORY_SAVE_RAM); #ifdef HAS_SRM // srm, compressed if (CFG_getSaveFormat() == SAVE_FORMAT_SRM) { - if(!rzipstream_write_file(filename, sram, sram_size)) + if (!rzipstream_write_file(filename, sram, sram_size)) LOG_error("rzipstream: Error writing SRAM data to file\n"); - } - else { - if(!filestream_write_file(filename, sram, sram_size)) + } else { + if (!filestream_write_file(filename, sram, sram_size)) LOG_error("filestream: Error writing SRAM data to file\n"); } #else @@ -804,21 +829,25 @@ static void SRAM_write(void) { /////////////////////////////////////// -static void RTC_getPath(char* filename) { +static void RTC_getPath(char *filename) +{ sprintf(filename, "%s/%s.rtc", core.saves_dir, game.alt_name); } -static void RTC_read(void) { +static void RTC_read(void) +{ size_t rtc_size = core.get_memory_size(RETRO_MEMORY_RTC); - if (!rtc_size) return; - + if (!rtc_size) + return; + char filename[MAX_PATH]; RTC_getPath(filename); printf("rtc path (read): %s\n", filename); - + FILE *rtc_file = fopen(filename, "r"); - if (!rtc_file) return; + if (!rtc_file) + return; - void* rtc = core.get_memory_data(RETRO_MEMORY_RTC); + void *rtc = core.get_memory_data(RETRO_MEMORY_RTC); if (!rtc || !fread(rtc, 1, rtc_size, rtc_file)) { LOG_error("Error reading RTC data\n"); @@ -826,14 +855,16 @@ static void RTC_read(void) { fclose(rtc_file); } -static void RTC_write(void) { +static void RTC_write(void) +{ size_t rtc_size = core.get_memory_size(RETRO_MEMORY_RTC); - if (!rtc_size) return; - + if (!rtc_size) + return; + char filename[MAX_PATH]; RTC_getPath(filename); printf("rtc path (write) size(%u): %s\n", rtc_size, filename); - + FILE *rtc_file = fopen(filename, "w"); if (!rtc_file) { LOG_error("Error opening RTC file: %s\n", strerror(errno)); @@ -855,55 +886,56 @@ static void RTC_write(void) { static int state_slot = 0; -static void formatStatePath(char* work_name, char* filename, const char* suffix) { - char* tmp = strrchr(work_name, '.'); +static void formatStatePath(char *work_name, char *filename, const char *suffix) +{ + char *tmp = strrchr(work_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; } sprintf(filename, "%s/%s%s", core.saves_dir, work_name, suffix); } -static void State_getPath(char* filename) { +static void State_getPath(char *filename) +{ char work_name[MAX_PATH]; // This is only here for compatibility with older versions of minarch, // should probably be removed at some point in the future. - if (CFG_getStateFormat() == STATE_FORMAT_SRM_EXTRADOT - || CFG_getStateFormat() == STATE_FORMAT_SRM_UNCOMRESSED_EXTRADOT) { + if (CFG_getStateFormat() == STATE_FORMAT_SRM_EXTRADOT || + CFG_getStateFormat() == STATE_FORMAT_SRM_UNCOMRESSED_EXTRADOT) { strcpy(work_name, game.alt_name); - char* tmp = strrchr(work_name, '.'); + char *tmp = strrchr(work_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; } - if(state_slot == AUTO_RESUME_SLOT) + if (state_slot == AUTO_RESUME_SLOT) sprintf(filename, "%s/%s.state.auto", core.states_dir, work_name); - else + else sprintf(filename, "%s/%s.state.%i", core.states_dir, work_name, state_slot); - } - else if (CFG_getStateFormat() == STATE_FORMAT_SRM - || CFG_getStateFormat() == STATE_FORMAT_SRM_UNCOMRESSED) { + } else if (CFG_getStateFormat() == STATE_FORMAT_SRM || CFG_getStateFormat() == STATE_FORMAT_SRM_UNCOMRESSED) { strcpy(work_name, game.alt_name); - char* tmp = strrchr(work_name, '.'); + char *tmp = strrchr(work_name, '.'); if (tmp != NULL && strlen(tmp) > 2 && strlen(tmp) <= 5) { tmp[0] = '\0'; } - if(state_slot == AUTO_RESUME_SLOT) + if (state_slot == AUTO_RESUME_SLOT) sprintf(filename, "%s/%s.state.auto", core.states_dir, work_name); - else if(state_slot == 0) + else if (state_slot == 0) sprintf(filename, "%s/%s.state", core.states_dir, work_name); - else + else sprintf(filename, "%s/%s.state%i", core.states_dir, work_name, state_slot); - } - else { + } else { sprintf(filename, "%s/%s.st%i", core.states_dir, game.alt_name, state_slot); } } -static void State_read(void) { // from picoarch +static void State_read(void) +{ // from picoarch size_t state_size = core.serialize_size(); - if (!state_size) return; + if (!state_size) + return; int was_ff = fast_forward; fast_forward = 0; @@ -925,8 +957,8 @@ static void State_read(void) { // from picoarch // srm, potentially compressed if (CFG_getStateFormat() == STATE_FORMAT_SRM || CFG_getStateFormat() == STATE_FORMAT_SRM_EXTRADOT) { state_rzfile = rzipstream_open(filename, RETRO_VFS_FILE_ACCESS_READ); - if(!state_rzfile) { - if (state_slot!=8) { // st8 is a default state in MiniUI and may not exist, that's okay + if (!state_rzfile) { + if (state_slot != 8) { // st8 is a default state in MiniUI and may not exist, that's okay LOG_error("Error opening state file: %s (%s)\n", filename, strerror(errno)); } goto error; @@ -943,23 +975,22 @@ static void State_read(void) { // from picoarch LOG_error("Error restoring save state: %s (%s)\n", filename, strerror(errno)); goto error; } - } - else { + } else { state_rfile = filestream_open(filename, RETRO_VFS_FILE_ACCESS_READ, 0); if (!state_rfile) { - if (state_slot!=8) { // st8 is a default state in MiniUI and may not exist, that's okay + if (state_slot != 8) { // st8 is a default state in MiniUI and may not exist, that's okay LOG_error("Error opening state file: %s (%s)\n", filename, strerror(errno)); } goto error; } - + // some cores report the wrong serialize size initially for some games, eg. mgba: Wario Land 4 // so we allow a size mismatch as long as the actual size fits in the buffer we've allocated if (state_size < filestream_read(state_rfile, state, state_size)) { LOG_error("Error reading state data from file: %s (%s)\n", filename, strerror(errno)); goto error; } - + if (!core.unserialize(state, state_size)) { LOG_error("Error restoring save state: %s (%s)\n", filename, strerror(errno)); goto error; @@ -967,18 +998,21 @@ static void State_read(void) { // from picoarch } error: - if (state) free(state); - if (state_rfile) filestream_close(state_rfile); - if (state_rzfile) rzipstream_close(state_rzfile); + if (state) + free(state); + if (state_rfile) + filestream_close(state_rfile); + if (state_rzfile) + rzipstream_close(state_rzfile); #else FILE *state_file = fopen(filename, "r"); if (!state_file) { - if (state_slot!=8) { // st8 is a default state in MiniUI and may not exist, that's okay + if (state_slot != 8) { // st8 is a default state in MiniUI and may not exist, that's okay LOG_error("Error opening state file: %s (%s)\n", filename, strerror(errno)); } goto error; } - + // some cores report the wrong serialize size initially for some games, eg. mgba: Wario Land 4 // so we allow a size mismatch as long as the actual size fits in the buffer we've allocated if (state_size < fread(state, 1, state_size, state_file)) { @@ -992,16 +1026,20 @@ static void State_read(void) { // from picoarch } error: - if (state) free(state); - if (state_file) fclose(state_file); + if (state) + free(state); + if (state_file) + fclose(state_file); #endif fast_forward = was_ff; } -static void State_write(void) { // from picoarch +static void State_write(void) +{ // from picoarch size_t state_size = core.serialize_size(); - if (!state_size) return; - + if (!state_size) + return; + int was_ff = fast_forward; fast_forward = 0; @@ -1015,25 +1053,25 @@ static void State_write(void) { // from picoarch LOG_error("Error serializing save state\n"); goto error; } - + char filename[MAX_PATH]; State_getPath(filename); #ifdef HAS_SRM if (CFG_getStateFormat() == STATE_FORMAT_SRM || CFG_getStateFormat() == STATE_FORMAT_SRM_EXTRADOT) { - if(!rzipstream_write_file(filename, state, state_size)) { + if (!rzipstream_write_file(filename, state, state_size)) { LOG_error("rzipstream: Error writing state data to file: %s\n", filename); goto error; } - } - else { - if(!filestream_write_file(filename, state, state_size)) { + } else { + if (!filestream_write_file(filename, state, state_size)) { LOG_error("filestream: Error writing state data to file: %s\n", filename); goto error; } } error: - if (state) free(state); + if (state) + free(state); #else FILE *state_file = fopen(filename, "w"); if (!state_file) { @@ -1044,24 +1082,29 @@ static void State_write(void) { // from picoarch LOG_error("Error writing state data to file: %s (%s)\n", filename, strerror(errno)); goto error; } - error: - if (state) free(state); - if (state_file) fclose(state_file); +error: + if (state) + free(state); + if (state_file) + fclose(state_file); #endif sync(); fast_forward = was_ff; } -static void State_autosave(void) { +static void State_autosave(void) +{ int last_state_slot = state_slot; state_slot = AUTO_RESUME_SLOT; State_write(); state_slot = last_state_slot; } -static void State_resume(void) { - if (!exists(RESUME_SLOT_PATH)) return; - +static void State_resume(void) +{ + if (!exists(RESUME_SLOT_PATH)) + return; + int last_state_slot = state_slot; state_slot = getInt(RESUME_SLOT_PATH); unlink(RESUME_SLOT_PATH); @@ -1072,19 +1115,19 @@ static void State_resume(void) { /////////////////////////////// typedef struct Option { - char* key; - char* name; // desc - char* desc; // info, truncated - char* full; // info, longer but possibly still truncated + char *key; + char *name; // desc + char *desc; // info, truncated + char *full; // info, longer but possibly still truncated char *category; - char* var; + char *var; int default_value; int value; int count; // TODO: drop this? int lock; int hidden; - char** values; - char** labels; + char **values; + char **labels; } Option; typedef struct OptionCategory { char *key; @@ -1094,250 +1137,49 @@ typedef struct OptionCategory { typedef struct OptionList { int count; int changed; - Option* options; - + Option *options; + int enabled_count; - Option** enabled_options; + Option **enabled_options; OptionCategory *categories; // OptionList_callback_t on_set; } OptionList; -static char* onoff_labels[] = { - "Off", - "On", - NULL -}; -static char* scaling_labels[] = { - "Native", - "Aspect", - "Aspect Screen", - "Fullscreen", - "Cropped", - NULL -}; -static char* resample_labels[] = { - "Low", - "Medium", - "High", - "Max", - NULL -}; -static char* ambient_labels[] = { - "Off", - "All", - "Top", - "FN", - "LR", - "Top/LR", - NULL -}; +static char *onoff_labels[] = {"Off", "On", NULL}; +static char *scaling_labels[] = {"Native", "Aspect", "Aspect Screen", "Fullscreen", "Cropped", NULL}; +static char *resample_labels[] = {"Low", "Medium", "High", "Max", NULL}; +static char *ambient_labels[] = {"Off", "All", "Top", "FN", "LR", "Top/LR", NULL}; -static char* effect_labels[] = { - "None", - "Line", - "Grid", - NULL -}; -static char* overlay_labels[] = { - "None", - NULL -}; +static char *effect_labels[] = {"None", "Line", "Grid", NULL}; +static char *overlay_labels[] = {"None", NULL}; // static char* sharpness_labels[] = { // "Sharp", // "Crisp", // "Soft", // NULL // }; -static char* sharpness_labels[] = { - "NEAREST", - "LINEAR", - NULL -}; -static char* tearing_labels[] = { - "Off", - "Lenient", - "Strict", - NULL -}; -static char* sync_ref_labels[] = { - "Auto", - "Screen", - "Native", - NULL -}; -static char* max_ff_labels[] = { - "None", - "2x", - "3x", - "4x", - "5x", - "6x", - "7x", - "8x", - NULL, +static char *sharpness_labels[] = {"NEAREST", "LINEAR", NULL}; +static char *tearing_labels[] = {"Off", "Lenient", "Strict", NULL}; +static char *sync_ref_labels[] = {"Auto", "Screen", "Native", NULL}; +static char *max_ff_labels[] = { + "None", "2x", "3x", "4x", "5x", "6x", "7x", "8x", NULL, }; -static char* offset_labels[] = { - "-64", - "-63", - "-62", - "-61", - "-60", - "-59", - "-58", - "-57", - "-56", - "-55", - "-54", - "-53", - "-52", - "-51", - "-50", - "-49", - "-48", - "-47", - "-46", - "-45", - "-44", - "-43", - "-42", - "-41", - "-40", - "-39", - "-38", - "-37", - "-36", - "-35", - "-34", - "-33", - "-32", - "-31", - "-30", - "-29", - "-28", - "-27", - "-26", - "-25", - "-24", - "-23", - "-22", - "-21", - "-20", - "-19", - "-18", - "-17", - "-16", - "-15", - "-14", - "-13", - "-12", - "-11", - "-10", - "-9", - "-8", - "-7", - "-6", - "-5", - "-4", - "-3", - "-2", - "-1", - "0", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - "29", - "30", - "31", - "32", - "33", - "34", - "35", - "36", - "37", - "38", - "39", - "40", - "41", - "42", - "43", - "44", - "45", - "46", - "47", - "48", - "49", - "50", - "51", - "52", - "53", - "54", - "55", - "56", - "57", - "58", - "59", - "60", - "61", - "62", - "63", - "64", - NULL, -}; -static char* nrofshaders_labels[] = { - "off", - "1", - "2", - "3", - NULL -}; -static char* shupscale_labels[] = { - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "screen", - NULL -}; -static char* shfilter_labels[] = { - "NEAREST", - "LINEAR", - NULL -}; -static char* shscaletype_labels[] = { - "source", - "relative", - NULL +static char *offset_labels[] = { + "-64", "-63", "-62", "-61", "-60", "-59", "-58", "-57", "-56", "-55", "-54", "-53", "-52", "-51", "-50", + "-49", "-48", "-47", "-46", "-45", "-44", "-43", "-42", "-41", "-40", "-39", "-38", "-37", "-36", "-35", + "-34", "-33", "-32", "-31", "-30", "-29", "-28", "-27", "-26", "-25", "-24", "-23", "-22", "-21", "-20", + "-19", "-18", "-17", "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9", "-8", "-7", "-6", "-5", + "-4", "-3", "-2", "-1", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", + "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", + "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", + "56", "57", "58", "59", "60", "61", "62", "63", "64", NULL, }; +static char *nrofshaders_labels[] = {"off", "1", "2", "3", NULL}; +static char *shupscale_labels[] = {"1", "2", "3", "4", "5", "6", "7", "8", "screen", NULL}; +static char *shfilter_labels[] = {"NEAREST", "LINEAR", NULL}; +static char *shscaletype_labels[] = {"source", "relative", NULL}; /////////////////////////////// @@ -1379,15 +1221,11 @@ enum { SHORTCUT_TOGGLE_TURBO_L2, SHORTCUT_TOGGLE_TURBO_R, SHORTCUT_TOGGLE_TURBO_R2, - // + // SHORTCUT_COUNT, }; -enum { - SYNC_SRC_AUTO, - SYNC_SRC_SCREEN, - SYNC_SRC_CORE -}; +enum { SYNC_SRC_AUTO, SYNC_SRC_SCREEN, SYNC_SRC_CORE }; enum { SH_EXTRASETTINGS, SH_SHADERS_PRESET, @@ -1411,10 +1249,11 @@ enum { }; #define LOCAL_BUTTON_COUNT 16 // depends on device -#define RETRO_BUTTON_COUNT 16 // allow L3/R3 to be remapped by user if desired, eg. Virtual Boy uses extra buttons for right d-pad +#define RETRO_BUTTON_COUNT \ + 16 // allow L3/R3 to be remapped by user if desired, eg. Virtual Boy uses extra buttons for right d-pad -typedef struct ButtonMapping { - char* name; +typedef struct ButtonMapping { + char *name; int retro; int local; // TODO: dislike this name... int mod; @@ -1423,118 +1262,83 @@ typedef struct ButtonMapping { } ButtonMapping; static ButtonMapping default_button_mapping[] = { // used if pak.cfg doesn't exist or doesn't have bindings - {"Up", RETRO_DEVICE_ID_JOYPAD_UP, BTN_ID_DPAD_UP}, - {"Down", RETRO_DEVICE_ID_JOYPAD_DOWN, BTN_ID_DPAD_DOWN}, - {"Left", RETRO_DEVICE_ID_JOYPAD_LEFT, BTN_ID_DPAD_LEFT}, - {"Right", RETRO_DEVICE_ID_JOYPAD_RIGHT, BTN_ID_DPAD_RIGHT}, - {"A Button", RETRO_DEVICE_ID_JOYPAD_A, BTN_ID_A}, - {"B Button", RETRO_DEVICE_ID_JOYPAD_B, BTN_ID_B}, - {"X Button", RETRO_DEVICE_ID_JOYPAD_X, BTN_ID_X}, - {"Y Button", RETRO_DEVICE_ID_JOYPAD_Y, BTN_ID_Y}, - {"Start", RETRO_DEVICE_ID_JOYPAD_START, BTN_ID_START}, - {"Select", RETRO_DEVICE_ID_JOYPAD_SELECT, BTN_ID_SELECT}, - {"L1 Button", RETRO_DEVICE_ID_JOYPAD_L, BTN_ID_L1}, - {"R1 Button", RETRO_DEVICE_ID_JOYPAD_R, BTN_ID_R1}, - {"L2 Button", RETRO_DEVICE_ID_JOYPAD_L2, BTN_ID_L2}, - {"R2 Button", RETRO_DEVICE_ID_JOYPAD_R2, BTN_ID_R2}, - {"L3 Button", RETRO_DEVICE_ID_JOYPAD_L3, BTN_ID_L3}, - {"R3 Button", RETRO_DEVICE_ID_JOYPAD_R3, BTN_ID_R3}, - {NULL,0,0} -}; + {"Up", RETRO_DEVICE_ID_JOYPAD_UP, BTN_ID_DPAD_UP}, + {"Down", RETRO_DEVICE_ID_JOYPAD_DOWN, BTN_ID_DPAD_DOWN}, + {"Left", RETRO_DEVICE_ID_JOYPAD_LEFT, BTN_ID_DPAD_LEFT}, + {"Right", RETRO_DEVICE_ID_JOYPAD_RIGHT, BTN_ID_DPAD_RIGHT}, + {"A Button", RETRO_DEVICE_ID_JOYPAD_A, BTN_ID_A}, + {"B Button", RETRO_DEVICE_ID_JOYPAD_B, BTN_ID_B}, + {"X Button", RETRO_DEVICE_ID_JOYPAD_X, BTN_ID_X}, + {"Y Button", RETRO_DEVICE_ID_JOYPAD_Y, BTN_ID_Y}, + {"Start", RETRO_DEVICE_ID_JOYPAD_START, BTN_ID_START}, + {"Select", RETRO_DEVICE_ID_JOYPAD_SELECT, BTN_ID_SELECT}, + {"L1 Button", RETRO_DEVICE_ID_JOYPAD_L, BTN_ID_L1}, + {"R1 Button", RETRO_DEVICE_ID_JOYPAD_R, BTN_ID_R1}, + {"L2 Button", RETRO_DEVICE_ID_JOYPAD_L2, BTN_ID_L2}, + {"R2 Button", RETRO_DEVICE_ID_JOYPAD_R2, BTN_ID_R2}, + {"L3 Button", RETRO_DEVICE_ID_JOYPAD_L3, BTN_ID_L3}, + {"R3 Button", RETRO_DEVICE_ID_JOYPAD_R3, BTN_ID_R3}, + {NULL, 0, 0}}; static ButtonMapping button_label_mapping[] = { // used to lookup the retro_id and local btn_id from button name - {"NONE", -1, BTN_ID_NONE}, - {"UP", RETRO_DEVICE_ID_JOYPAD_UP, BTN_ID_DPAD_UP}, - {"DOWN", RETRO_DEVICE_ID_JOYPAD_DOWN, BTN_ID_DPAD_DOWN}, - {"LEFT", RETRO_DEVICE_ID_JOYPAD_LEFT, BTN_ID_DPAD_LEFT}, - {"RIGHT", RETRO_DEVICE_ID_JOYPAD_RIGHT, BTN_ID_DPAD_RIGHT}, - {"A", RETRO_DEVICE_ID_JOYPAD_A, BTN_ID_A}, - {"B", RETRO_DEVICE_ID_JOYPAD_B, BTN_ID_B}, - {"X", RETRO_DEVICE_ID_JOYPAD_X, BTN_ID_X}, - {"Y", RETRO_DEVICE_ID_JOYPAD_Y, BTN_ID_Y}, - {"START", RETRO_DEVICE_ID_JOYPAD_START, BTN_ID_START}, - {"SELECT", RETRO_DEVICE_ID_JOYPAD_SELECT, BTN_ID_SELECT}, - {"L1", RETRO_DEVICE_ID_JOYPAD_L, BTN_ID_L1}, - {"R1", RETRO_DEVICE_ID_JOYPAD_R, BTN_ID_R1}, - {"L2", RETRO_DEVICE_ID_JOYPAD_L2, BTN_ID_L2}, - {"R2", RETRO_DEVICE_ID_JOYPAD_R2, BTN_ID_R2}, - {"L3", RETRO_DEVICE_ID_JOYPAD_L3, BTN_ID_L3}, - {"R3", RETRO_DEVICE_ID_JOYPAD_R3, BTN_ID_R3}, - {NULL,0,0} -}; -static ButtonMapping core_button_mapping[RETRO_BUTTON_COUNT+1] = {0}; - -static const char* device_button_names[LOCAL_BUTTON_COUNT] = { - [BTN_ID_DPAD_UP] = "UP", - [BTN_ID_DPAD_DOWN] = "DOWN", - [BTN_ID_DPAD_LEFT] = "LEFT", - [BTN_ID_DPAD_RIGHT] = "RIGHT", - [BTN_ID_SELECT] = "SELECT", - [BTN_ID_START] = "START", - [BTN_ID_Y] = "Y", - [BTN_ID_X] = "X", - [BTN_ID_B] = "B", - [BTN_ID_A] = "A", - [BTN_ID_L1] = "L1", - [BTN_ID_R1] = "R1", - [BTN_ID_L2] = "L2", - [BTN_ID_R2] = "R2", - [BTN_ID_L3] = "L3", - [BTN_ID_R3] = "R3", + {"NONE", -1, BTN_ID_NONE}, + {"UP", RETRO_DEVICE_ID_JOYPAD_UP, BTN_ID_DPAD_UP}, + {"DOWN", RETRO_DEVICE_ID_JOYPAD_DOWN, BTN_ID_DPAD_DOWN}, + {"LEFT", RETRO_DEVICE_ID_JOYPAD_LEFT, BTN_ID_DPAD_LEFT}, + {"RIGHT", RETRO_DEVICE_ID_JOYPAD_RIGHT, BTN_ID_DPAD_RIGHT}, + {"A", RETRO_DEVICE_ID_JOYPAD_A, BTN_ID_A}, + {"B", RETRO_DEVICE_ID_JOYPAD_B, BTN_ID_B}, + {"X", RETRO_DEVICE_ID_JOYPAD_X, BTN_ID_X}, + {"Y", RETRO_DEVICE_ID_JOYPAD_Y, BTN_ID_Y}, + {"START", RETRO_DEVICE_ID_JOYPAD_START, BTN_ID_START}, + {"SELECT", RETRO_DEVICE_ID_JOYPAD_SELECT, BTN_ID_SELECT}, + {"L1", RETRO_DEVICE_ID_JOYPAD_L, BTN_ID_L1}, + {"R1", RETRO_DEVICE_ID_JOYPAD_R, BTN_ID_R1}, + {"L2", RETRO_DEVICE_ID_JOYPAD_L2, BTN_ID_L2}, + {"R2", RETRO_DEVICE_ID_JOYPAD_R2, BTN_ID_R2}, + {"L3", RETRO_DEVICE_ID_JOYPAD_L3, BTN_ID_L3}, + {"R3", RETRO_DEVICE_ID_JOYPAD_R3, BTN_ID_R3}, + {NULL, 0, 0}}; +static ButtonMapping core_button_mapping[RETRO_BUTTON_COUNT + 1] = {0}; + +static const char *device_button_names[LOCAL_BUTTON_COUNT] = { + [BTN_ID_DPAD_UP] = "UP", + [BTN_ID_DPAD_DOWN] = "DOWN", + [BTN_ID_DPAD_LEFT] = "LEFT", + [BTN_ID_DPAD_RIGHT] = "RIGHT", + [BTN_ID_SELECT] = "SELECT", + [BTN_ID_START] = "START", + [BTN_ID_Y] = "Y", + [BTN_ID_X] = "X", + [BTN_ID_B] = "B", + [BTN_ID_A] = "A", + [BTN_ID_L1] = "L1", + [BTN_ID_R1] = "R1", + [BTN_ID_L2] = "L2", + [BTN_ID_R2] = "R2", + [BTN_ID_L3] = "L3", + [BTN_ID_R3] = "R3", }; // NOTE: these must be in BTN_ID_ order also off by 1 because of NONE (which is -1 in BTN_ID_ land) -static char* button_labels[] = { +static char *button_labels[] = { "NONE", // displayed by default - "UP", - "DOWN", - "LEFT", - "RIGHT", - "A", - "B", - "X", - "Y", - "START", - "SELECT", - "L1", - "R1", - "L2", - "R2", - "L3", - "R3", - "MENU+UP", - "MENU+DOWN", - "MENU+LEFT", - "MENU+RIGHT", - "MENU+A", - "MENU+B", - "MENU+X", - "MENU+Y", - "MENU+START", - "MENU+SELECT", - "MENU+L1", - "MENU+R1", - "MENU+L2", - "MENU+R2", - "MENU+L3", - "MENU+R3", - NULL, + "UP", "DOWN", "LEFT", "RIGHT", "A", "B", "X", "Y", "START", + "SELECT", "L1", "R1", "L2", "R2", "L3", "R3", "MENU+UP", "MENU+DOWN", + "MENU+LEFT", "MENU+RIGHT", "MENU+A", "MENU+B", "MENU+X", "MENU+Y", "MENU+START", "MENU+SELECT", "MENU+L1", + "MENU+R1", "MENU+L2", "MENU+R2", "MENU+L3", "MENU+R3", NULL, }; -static char* overclock_labels[] = { - "Powersave", - "Normal", - "Performance", - "Auto", - NULL, +static char *overclock_labels[] = { + "Powersave", "Normal", "Performance", "Auto", NULL, }; // TODO: this should be provided by the core -static char* gamepad_labels[] = { +static char *gamepad_labels[] = { "Standard", "DualShock", NULL, }; -static char* gamepad_values[] = { +static char *gamepad_values[] = { "1", "517", NULL, @@ -1546,489 +1350,579 @@ enum { CONFIG_GAME, }; -static inline char* getScreenScalingDesc(void) { +static inline char *getScreenScalingDesc(void) +{ if (GFX_supportsOverscan()) { - return "Native uses integer scaling. Aspect uses core nreported aspect ratio.\nAspect screen uses screen aspect ratio\n Fullscreen has non-square\npixels. Cropped is integer scaled then cropped."; - } - else { - return "Native uses integer scaling.\nAspect uses core reported aspect ratio.\nAspect screen uses screen aspect ratio\nFullscreen has non-square pixels."; + return "Native uses integer scaling. Aspect uses core nreported aspect ratio.\nAspect screen uses screen " + "aspect ratio\n Fullscreen has non-square\npixels. Cropped is integer scaled then cropped."; + } else { + return "Native uses integer scaling.\nAspect uses core reported aspect ratio.\nAspect screen uses screen " + "aspect ratio\nFullscreen has non-square pixels."; } } -static inline int getScreenScalingCount(void) { +static inline int getScreenScalingCount(void) +{ return GFX_supportsOverscan() ? 5 : 4; } - + static struct Config { - char* system_cfg; // system.cfg based on system limitations - char* default_cfg; // pak.cfg based on platform limitations - char* user_cfg; // minarch.cfg or game.cfg based on user preference - char* shaders_preset; // minarch.cfg or game.cfg based on user preference - char* device_tag; + char *system_cfg; // system.cfg based on system limitations + char *default_cfg; // pak.cfg based on platform limitations + char *user_cfg; // minarch.cfg or game.cfg based on user preference + char *shaders_preset; // minarch.cfg or game.cfg based on user preference + char *device_tag; OptionList frontend; OptionList core; OptionList shaders; OptionList shaderpragmas[3]; - ButtonMapping* controls; - ButtonMapping* shortcuts; + ButtonMapping *controls; + ButtonMapping *shortcuts; int loaded; int initialized; } config = { - .frontend = { // (OptionList) - .count = FE_OPT_COUNT, - .options = (Option[]){ - [FE_OPT_SCALING] = { - .key = "minarch_screen_scaling", - .name = "Screen Scaling", - .desc = NULL, // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 3, // will call getScreenScalingCount() - .values = scaling_labels, - .labels = scaling_labels, - }, - [FE_OPT_RESAMPLING] = { - .key = "minarch__resampling_quality", - .name = "Audio Resampling Quality", - .desc = "Resampling quality higher takes more CPU", // will call getScreenScalingDesc() - .default_value = 2, - .value = 2, - .count = 4, - .values = resample_labels, - .labels = resample_labels, - }, - [FE_OPT_AMBIENT] = { - .key = "minarch_ambient", - .name = "Ambient Mode", - .desc = "Makes your leds follow on screen colors", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 6, - .values = ambient_labels, - .labels = ambient_labels, - }, - [FE_OPT_EFFECT] = { - .key = "minarch_screen_effect", - .name = "Screen Effect", - .desc = "Grid simulates an LCD grid.\nLine simulates CRT scanlines.\nEffects usually look best at native scaling.", - .default_value = 0, - .value = 0, - .count = 3, - .values = effect_labels, - .labels = effect_labels, - }, - [FE_OPT_OVERLAY] = { - .key = "minarch_overlay", - .name = "Overlay", - .desc = "Choose a custom overlay png from the Overlays folder", - .default_value = 0, - .value = 0, - .count = 1, - .values = overlay_labels, - .labels = overlay_labels, - }, - [FE_OPT_SCREENX] = { - .key = "minarch_screen_offsetx", - .name = "Offset screen X", - .desc = "Offset X pixels", - .default_value = 64, - .value = 64, - .count = 129, - .values = offset_labels, - .labels = offset_labels, - }, - [FE_OPT_SCREENY] = { - .key = "minarch_screen_offsety", - .name = "Offset screen Y", - .desc = "Offset Y pixels", - .default_value = 64, - .value = 64, - .count = 129, - .values = offset_labels, - .labels = offset_labels, - }, - [FE_OPT_SHARPNESS] = { - // .key = "minarch_screen_sharpness", - .key = "minarch_scale_filter", - .name = "Screen Sharpness", - .desc = "LINEAR smooths lines, but works better when final image is at higher resolution, so either core that outputs higher resolution or upscaling with shaders", - .default_value = 1, - .value = 1, - .count = 3, - .values = sharpness_labels, - .labels = sharpness_labels, - }, - [FE_OPT_TEARING] = { - .key = "minarch_prevent_tearing", - .name = "VSync", - .desc = "Wait for vsync before drawing the next frame.\nLenient only waits when within frame budget.\nStrict always waits.", - .default_value = VSYNC_LENIENT, - .value = VSYNC_LENIENT, - .count = 3, - .values = tearing_labels, - .labels = tearing_labels, - }, - [FE_OPT_SYNC_REFERENCE] = { - .key = "minarch_sync_reference", - .name = "Core Sync", - .desc = "Choose what should be used as a\nreference for the frame rate.\n\"Native\" uses the emulator frame rate,\n\"Screen\" uses the frame rate of the screen.", - .default_value = SYNC_SRC_AUTO, - .value = SYNC_SRC_AUTO, - .count = 3, - .values = sync_ref_labels, - .labels = sync_ref_labels, - }, - [FE_OPT_OVERCLOCK] = { - .key = "minarch_cpu_speed", - .name = "CPU Speed", - .desc = "Over- or underclock the CPU to prioritize\npure performance or power savings.", - .default_value = 3, - .value = 3, - .count = 4, - .values = overclock_labels, - .labels = overclock_labels, - }, - [FE_OPT_DEBUG] = { - .key = "minarch_debug_hud", - .name = "Debug HUD", - .desc = "Show frames per second, cpu load,\nresolution, and scaler information.", - .default_value = 0, - .value = 0, - .count = 2, - .values = onoff_labels, - .labels = onoff_labels, - }, - [FE_OPT_MAXFF] = { - .key = "minarch_max_ff_speed", - .name = "Max FF Speed", - .desc = "Fast forward will not exceed the\nselected speed (but may be less\ndepending on game and emulator).", - .default_value = 3, // 4x - .value = 3, // 4x - .count = 8, - .values = max_ff_labels, - .labels = max_ff_labels, - }, - [FE_OPT_FF_AUDIO] = { - .key = "minarch__ff_audio", - .name = "Fast forward audio", - .desc = "Play or mute audio when fast forwarding.", - .default_value = 0, - .value = 0, - .count = 2, - .values = onoff_labels, - .labels = onoff_labels, - }, - [FE_OPT_COUNT] = {NULL} - } - }, - .core = { // (OptionList) - .count = 0, - .options = (Option[]){ - {NULL}, + .frontend = + {// (OptionList) + .count = FE_OPT_COUNT, + .options = + (Option[]){[FE_OPT_SCALING] = + { + .key = "minarch_screen_scaling", + .name = "Screen Scaling", + .desc = NULL, // will call getScreenScalingDesc() + .default_value = 1, + .value = 1, + .count = 3, // will call getScreenScalingCount() + .values = scaling_labels, + .labels = scaling_labels, + }, + [FE_OPT_RESAMPLING] = + { + .key = "minarch__resampling_quality", + .name = "Audio Resampling Quality", + .desc = "Resampling quality higher takes more CPU", // will call getScreenScalingDesc() + .default_value = 2, + .value = 2, + .count = 4, + .values = resample_labels, + .labels = resample_labels, + }, + [FE_OPT_AMBIENT] = + { + .key = "minarch_ambient", + .name = "Ambient Mode", + .desc = "Makes your leds follow on screen colors", // will call getScreenScalingDesc() + .default_value = 0, + .value = 0, + .count = 6, + .values = ambient_labels, + .labels = ambient_labels, + }, + [FE_OPT_EFFECT] = + { + .key = "minarch_screen_effect", + .name = "Screen Effect", + .desc = "Grid simulates an LCD grid.\nLine simulates CRT scanlines.\nEffects usually " + "look best at native scaling.", + .default_value = 0, + .value = 0, + .count = 3, + .values = effect_labels, + .labels = effect_labels, + }, + [FE_OPT_OVERLAY] = + { + .key = "minarch_overlay", + .name = "Overlay", + .desc = "Choose a custom overlay png from the Overlays folder", + .default_value = 0, + .value = 0, + .count = 1, + .values = overlay_labels, + .labels = overlay_labels, + }, + [FE_OPT_SCREENX] = + { + .key = "minarch_screen_offsetx", + .name = "Offset screen X", + .desc = "Offset X pixels", + .default_value = 64, + .value = 64, + .count = 129, + .values = offset_labels, + .labels = offset_labels, + }, + [FE_OPT_SCREENY] = + { + .key = "minarch_screen_offsety", + .name = "Offset screen Y", + .desc = "Offset Y pixels", + .default_value = 64, + .value = 64, + .count = 129, + .values = offset_labels, + .labels = offset_labels, + }, + [FE_OPT_SHARPNESS] = + { + // .key = "minarch_screen_sharpness", + .key = "minarch_scale_filter", + .name = "Screen Sharpness", + .desc = + "LINEAR smooths lines, but works better when final image is at higher resolution, " + "so either core that outputs higher resolution or upscaling with shaders", + .default_value = 1, + .value = 1, + .count = 3, + .values = sharpness_labels, + .labels = sharpness_labels, + }, + [FE_OPT_TEARING] = + { + .key = "minarch_prevent_tearing", + .name = "VSync", + .desc = "Wait for vsync before drawing the next frame.\nLenient only waits when within " + "frame budget.\nStrict always waits.", + .default_value = VSYNC_LENIENT, + .value = VSYNC_LENIENT, + .count = 3, + .values = tearing_labels, + .labels = tearing_labels, + }, + [FE_OPT_SYNC_REFERENCE] = + { + .key = "minarch_sync_reference", + .name = "Core Sync", + .desc = "Choose what should be used as a\nreference for the frame rate.\n\"Native\" " + "uses the emulator frame rate,\n\"Screen\" uses the frame rate of the screen.", + .default_value = SYNC_SRC_AUTO, + .value = SYNC_SRC_AUTO, + .count = 3, + .values = sync_ref_labels, + .labels = sync_ref_labels, + }, + [FE_OPT_OVERCLOCK] = + { + .key = "minarch_cpu_speed", + .name = "CPU Speed", + .desc = "Over- or underclock the CPU to prioritize\npure performance or power savings.", + .default_value = 3, + .value = 3, + .count = 4, + .values = overclock_labels, + .labels = overclock_labels, + }, + [FE_OPT_DEBUG] = + { + .key = "minarch_debug_hud", + .name = "Debug HUD", + .desc = "Show frames per second, cpu load,\nresolution, and scaler information.", + .default_value = 0, + .value = 0, + .count = 2, + .values = onoff_labels, + .labels = onoff_labels, + }, + [FE_OPT_MAXFF] = + { + .key = "minarch_max_ff_speed", + .name = "Max FF Speed", + .desc = "Fast forward will not exceed the\nselected speed (but may be less\ndepending " + "on game and emulator).", + .default_value = 3, // 4x + .value = 3, // 4x + .count = 8, + .values = max_ff_labels, + .labels = max_ff_labels, + }, + [FE_OPT_FF_AUDIO] = + { + .key = "minarch__ff_audio", + .name = "Fast forward audio", + .desc = "Play or mute audio when fast forwarding.", + .default_value = 0, + .value = 0, + .count = 2, + .values = onoff_labels, + .labels = onoff_labels, + }, + [FE_OPT_COUNT] = {NULL}}}, + .core = + { + // (OptionList) + .count = 0, + .options = + (Option[]){ + {NULL}, + }, }, - }, - .shaders = { // (OptionList) - .count = 18, - .options = (Option[]){ - [SH_EXTRASETTINGS] = { - .key = "minarch_shaders_settings", - .name = "Optional Shaders Settings", - .desc = "If shaders have extra settings they will show up in this settings menu", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 0, - .values = NULL, - .labels = NULL, - }, - [SH_SHADERS_PRESET] = { - .key = "minarch_shaders_preset", - .name = "Shader / Emulator Settings Preset", - .desc = "Load a premade shaders/emulators config.\nTo try out a preset, exit the game without saving settings!", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 0, - .values = NULL, - .labels = NULL, - }, - [SH_NROFSHADERS] = { - .key = "minarch_nrofshaders", - .name = "Number of Shaders", - .desc = "Number of shaders 1 to 3", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 4, - .values = nrofshaders_labels, - .labels = nrofshaders_labels, - }, - - [SH_SHADER1] = { - .key = "minarch_shader1", - .name = "Shader 1", - .desc = "Shader 1 program to run", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 0, - .values = NULL, - .labels = NULL, - }, - [SH_SHADER1_FILTER] = { - .key = "minarch_shader1_filter", - .name = "Shader 1 Filter", - .desc = "Method of upscaling, NEAREST or LINEAR", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 2, - .values = shfilter_labels, - .labels = shfilter_labels, - }, - [SH_SRCTYPE1] = { - .key = "minarch_shader1_srctype", - .name = "Shader 1 Source type", - .desc = "This will choose resolution source to scale from", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 2, - .values = shscaletype_labels, - .labels = shscaletype_labels, - }, - [SH_SCALETYPE1] = { - .key = "minarch_shader1_scaletype", - .name = "Shader 1 Texture Type", - .desc = "This will choose resolution source to scale from", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 2, - .values = shscaletype_labels, - .labels = shscaletype_labels, - }, - [SH_UPSCALE1] = { - .key = "minarch_shader1_upscale", - .name = "Shader 1 Scale", - .desc = "This will scale images x times,\nscreen scales to screens resolution (can hit performance)", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 9, - .values = shupscale_labels, - .labels = shupscale_labels, - }, - [SH_SHADER2] = { - .key = "minarch_shader2", - .name = "Shader 2", - .desc = "Shader 2 program to run", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 0, - .values = NULL, - .labels = NULL, - - }, - [SH_SHADER2_FILTER] = { - .key = "minarch_shader2_filter", - .name = "Shader 2 Filter", - .desc = "Method of upscaling, NEAREST or LINEAR", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 2, - .values = shfilter_labels, - .labels = shfilter_labels, - }, - [SH_SRCTYPE2] = { - .key = "minarch_shader2_srctype", - .name = "Shader 2 Source type", - .desc = "This will choose resolution source to scale from", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 2, - .values = shscaletype_labels, - .labels = shscaletype_labels, - }, - [SH_SCALETYPE2] = { - .key = "minarch_shader2_scaletype", - .name = "Shader 2 Texture Type", - .desc = "This will choose resolution source to scale from", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 2, - .values = shscaletype_labels, - .labels = shscaletype_labels, - }, - [SH_UPSCALE2] = { - .key = "minarch_shader2_upscale", - .name = "Shader 2 Scale", - .desc = "This will scale images x times,\nscreen scales to screens resolution (can hit performance)", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 9, - .values = shupscale_labels, - .labels = shupscale_labels, - }, - [SH_SHADER3] = { - .key = "minarch_shader3", - .name = "Shader 3", - .desc = "Shader 3 program to run", // will call getScreenScalingDesc() - .default_value = 2, - .value = 2, - .count = 0, - .values = NULL, - .labels = NULL, - - }, - [SH_SHADER3_FILTER] = { - .key = "minarch_shader3_filter", - .name = "Shader 3 Filter", - .desc = "Method of upscaling, NEAREST or LINEAR", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 2, - .values = shfilter_labels, - .labels = shfilter_labels, - }, - [SH_SRCTYPE3] = { - .key = "minarch_shader3_srctype", - .name = "Shader 3 Source type", - .desc = "This will choose resolution source to scale from", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 2, - .values = shscaletype_labels, - .labels = shscaletype_labels, - }, - [SH_SCALETYPE3] = { - .key = "minarch_shader3_scaletype", - .name = "Shader 3 Texture Type", - .desc = "This will choose resolution source to scale from", // will call getScreenScalingDesc() - .default_value = 1, - .value = 1, - .count = 2, - .values = shscaletype_labels, - .labels = shscaletype_labels, - }, - [SH_UPSCALE3] = { - .key = "minarch_shader3_upscale", - .name = "Shader 3 Scale", - .desc = "This will scale images x times,\nscreen scales to screens resolution (can hit performance)", // will call getScreenScalingDesc() - .default_value = 0, - .value = 0, - .count = 9, - .values = shupscale_labels, - .labels = shupscale_labels, - }, - {NULL} + .shaders = + { + // (OptionList) + .count = 18, + .options = + (Option + []){[SH_EXTRASETTINGS] = + { + .key = + "minarch_shaders_settings", + .name = "Optional Shaders Settings", + .desc = "If shaders have extra settings they will show up in this settings menu", // will + // call + // getScreenScalingDesc() + .default_value = 1, + .value = 1, + .count = 0, + .values = NULL, + .labels = NULL, + }, + [SH_SHADERS_PRESET] = + { + .key = + "minarch_shaders_preset", + .name = "Shader / Emulator Settings Preset", + .desc = "Load a premade shaders/emulators config.\nTo try out a preset, exit the game " + "without saving settings!", // will call getScreenScalingDesc() + .default_value = 1, + .value = + 1, + .count = + 0, + .values = NULL, + .labels = NULL, + }, + [SH_NROFSHADERS] = + { + .key = + "minarch_nrofshaders", + .name = "Number of Shaders", + .desc = "Number of shaders 1 to 3", // will call getScreenScalingDesc() + .default_value = 0, + .value = + 0, + .count = + 4, + .values = nrofshaders_labels, + .labels = nrofshaders_labels, + }, + + [SH_SHADER1] = + { + .key = + "minarch_shader1", + .name = "Shader 1", + .desc = "Shader 1 program to run", // will call getScreenScalingDesc() + .default_value = 1, + .value = + 1, + .count = + 0, + .values = NULL, + .labels = NULL, + }, + [SH_SHADER1_FILTER] = + { + .key = + "minarch_shader1_filter", + .name = "Shader 1 Filter", + .desc = "Method of upscaling, NEAREST or LINEAR", // will call getScreenScalingDesc() + .default_value = 1, + .value = + 1, + .count = + 2, + .values = shfilter_labels, + .labels = shfilter_labels, + }, + [SH_SRCTYPE1] = + { + .key = + "minarch_shader1_srctype", + .name = "Shader 1 Source type", + .desc = "This will choose resolution source to scale from", // will call + // getScreenScalingDesc() + .default_value = 0, + .value = + 0, + .count = + 2, + .values = shscaletype_labels, + .labels = shscaletype_labels, + }, + [SH_SCALETYPE1] = + { + .key = + "minarch_shader1_scaletype", + .name = "Shader 1 Texture Type", + .desc = "This will choose resolution source to scale from", // will call + // getScreenScalingDesc() + .default_value = 1, + .value = + 1, + .count = + 2, + .values = shscaletype_labels, + .labels = shscaletype_labels, + }, + [SH_UPSCALE1] = + { + .key = + "minarch_shader1_upscale", + .name = "Shader 1 Scale", + .desc = "This will scale images x times,\nscreen scales to screens resolution (can " + "hit performance)", // will call getScreenScalingDesc() + .default_value = 1, + .value = + 1, + .count = + 9, + .values = shupscale_labels, + .labels = shupscale_labels, + }, + [SH_SHADER2] = + { + .key = + "minarch_shader2", + .name = "Shader 2", + .desc = "Shader 2 program to run", // will call getScreenScalingDesc() + .default_value = 0, + .value = + 0, + .count = + 0, + .values = NULL, + .labels = NULL, + + }, + [SH_SHADER2_FILTER] = + { + .key = + "minarch_shader2_filter", + .name = "Shader 2 Filter", + .desc = "Method of upscaling, NEAREST or LINEAR", // will call getScreenScalingDesc() + .default_value = 0, + .value = + 0, + .count = + 2, + .values = shfilter_labels, + .labels = shfilter_labels, + }, + [SH_SRCTYPE2] = + { + .key = + "minarch_shader2_srctype", + .name = "Shader 2 Source type", + .desc = "This will choose resolution source to scale from", // will call + // getScreenScalingDesc() + .default_value = 0, + .value = 0, + .count = 2, + .values = shscaletype_labels, + .labels = shscaletype_labels, + }, + [SH_SCALETYPE2] = + { + .key = + "minarch_shader2_scaletype", + .name = "Shader 2 Texture Type", + .desc = "This will choose resolution source to scale from", // will call + // getScreenScalingDesc() + .default_value = 1, + .value = 1, + .count = 2, + .values = shscaletype_labels, + .labels = shscaletype_labels, + }, + [SH_UPSCALE2] = + { + .key = + "minarch_shader2_upscale", + .name = "Shader 2 Scale", + .desc = "This will scale images x times,\nscreen scales to screens resolution (can " + "hit performance)", // will call getScreenScalingDesc() + .default_value = 0, + .value = 0, + .count = 9, + .values = shupscale_labels, + .labels = shupscale_labels, + }, + [SH_SHADER3] = + { + .key = + "minarch_shader3", + .name = "Shader 3", + .desc = "Shader 3 program to run", // will call getScreenScalingDesc() + .default_value = 2, + .value = 2, + .count = 0, + .values = NULL, + .labels = NULL, + + }, + [SH_SHADER3_FILTER] = + { + .key = + "minarch_shader3_filter", + .name = "Shader 3 Filter", + .desc = "Method of upscaling, NEAREST or LINEAR", // will call getScreenScalingDesc() + .default_value = 0, + .value = 0, + .count = 2, + .values = shfilter_labels, + .labels = shfilter_labels, + }, + [SH_SRCTYPE3] = + { + .key = + "minarch_shader3_srctype", + .name = "Shader 3 Source type", + .desc = "This will choose resolution source to scale from", // will call + // getScreenScalingDesc() + .default_value = 0, + .value = 0, + .count = 2, + .values = shscaletype_labels, + .labels = shscaletype_labels, + }, + [SH_SCALETYPE3] = + { + .key = "minarch_shader3_scaletype", + .name = "Shader 3 Texture Type", + .desc = "This will choose resolution source to scale from", // will call + // getScreenScalingDesc() + .default_value = 1, + .value = 1, + .count = 2, + .values = shscaletype_labels, + .labels = shscaletype_labels, + }, + [SH_UPSCALE3] = + { + .key = "minarch_shader3_upscale", + .name = "Shader 3 Scale", + .desc = "This will scale images x times,\nscreen scales to screens resolution (can " + "hit performance)", // will call getScreenScalingDesc() + .default_value = 0, + .value = 0, + .count = 9, + .values = shupscale_labels, + .labels = shupscale_labels, + }, + {NULL}}, }, - }, .shaderpragmas = {{ .count = 0, .options = NULL, }}, .controls = default_button_mapping, - .shortcuts = (ButtonMapping[]){ - [SHORTCUT_SAVE_STATE] = {"Save State", -1, BTN_ID_NONE, 0}, - [SHORTCUT_LOAD_STATE] = {"Load State", -1, BTN_ID_NONE, 0}, - [SHORTCUT_RESET_GAME] = {"Reset Game", -1, BTN_ID_NONE, 0}, - [SHORTCUT_SAVE_QUIT] = {"Save & Quit", -1, BTN_ID_NONE, 0}, - [SHORTCUT_CYCLE_SCALE] = {"Cycle Scaling", -1, BTN_ID_NONE, 0}, - [SHORTCUT_CYCLE_EFFECT] = {"Cycle Effect", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_FF] = {"Toggle FF", -1, BTN_ID_NONE, 0}, - [SHORTCUT_HOLD_FF] = {"Hold FF", -1, BTN_ID_NONE, 0}, - [SHORTCUT_GAMESWITCHER] = {"Game Switcher", -1, BTN_ID_NONE, 0}, - [SHORTCUT_SCREENSHOT] = {"Screenshot", -1, BTN_ID_NONE, 0}, - // Trimui only - [SHORTCUT_TOGGLE_TURBO_A] = {"Toggle Turbo A", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_TURBO_B] = {"Toggle Turbo B", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_TURBO_X] = {"Toggle Turbo X", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_TURBO_Y] = {"Toggle Turbo Y", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_TURBO_L] = {"Toggle Turbo L", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_TURBO_L2] = {"Toggle Turbo L2", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_TURBO_R] = {"Toggle Turbo R", -1, BTN_ID_NONE, 0}, - [SHORTCUT_TOGGLE_TURBO_R2] = {"Toggle Turbo R2", -1, BTN_ID_NONE, 0}, - // ----- - {NULL} - }, + .shortcuts = (ButtonMapping[]){[SHORTCUT_SAVE_STATE] = {"Save State", -1, BTN_ID_NONE, 0}, + [SHORTCUT_LOAD_STATE] = {"Load State", -1, BTN_ID_NONE, 0}, + [SHORTCUT_RESET_GAME] = {"Reset Game", -1, BTN_ID_NONE, 0}, + [SHORTCUT_SAVE_QUIT] = {"Save & Quit", -1, BTN_ID_NONE, 0}, + [SHORTCUT_CYCLE_SCALE] = {"Cycle Scaling", -1, BTN_ID_NONE, 0}, + [SHORTCUT_CYCLE_EFFECT] = {"Cycle Effect", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_FF] = {"Toggle FF", -1, BTN_ID_NONE, 0}, + [SHORTCUT_HOLD_FF] = {"Hold FF", -1, BTN_ID_NONE, 0}, + [SHORTCUT_GAMESWITCHER] = {"Game Switcher", -1, BTN_ID_NONE, 0}, + [SHORTCUT_SCREENSHOT] = {"Screenshot", -1, BTN_ID_NONE, 0}, + // Trimui only + [SHORTCUT_TOGGLE_TURBO_A] = {"Toggle Turbo A", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_TURBO_B] = {"Toggle Turbo B", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_TURBO_X] = {"Toggle Turbo X", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_TURBO_Y] = {"Toggle Turbo Y", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_TURBO_L] = {"Toggle Turbo L", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_TURBO_L2] = {"Toggle Turbo L2", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_TURBO_R] = {"Toggle Turbo R", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TOGGLE_TURBO_R2] = {"Toggle Turbo R2", -1, BTN_ID_NONE, 0}, + // ----- + {NULL}}, }; -static int Config_getValue(char* cfg, const char* key, char* out_value, int* lock) { // gets value from string - char* tmp = cfg; +static int Config_getValue(char *cfg, const char *key, char *out_value, int *lock) +{ // gets value from string + char *tmp = cfg; while ((tmp = strstr(tmp, key))) { - if (lock!=NULL && tmp>cfg && *(tmp-1)=='-') *lock = 1; // prefixed with a `-` means lock + if (lock != NULL && tmp > cfg && *(tmp - 1) == '-') + *lock = 1; // prefixed with a `-` means lock tmp += strlen(key); - if (!strncmp(tmp, " = ", 3)) break; // matched + if (!strncmp(tmp, " = ", 3)) + break; // matched }; - if (!tmp) return 0; + if (!tmp) + return 0; tmp += 3; - + strncpy(out_value, tmp, 256); out_value[256 - 1] = '\0'; tmp = strchr(out_value, '\n'); - if (!tmp) tmp = strchr(out_value, '\r'); - if (tmp) *tmp = '\0'; + if (!tmp) + tmp = strchr(out_value, '\r'); + if (tmp) + *tmp = '\0'; // LOG_info("\t%s = %s (%s)\n", key, out_value, (lock && *lock) ? "hidden":"shown"); return 1; } - - - -static void setOverclock(int i) { - overclock = i; - switch (i) { - case 0: { - useAutoCpu = 0; - PWR_setCPUSpeed(CPU_SPEED_POWERSAVE); - break; - } - case 1: { - useAutoCpu = 0; - PWR_setCPUSpeed(CPU_SPEED_NORMAL); - break; - } - case 2: { - useAutoCpu = 0; - PWR_setCPUSpeed(CPU_SPEED_PERFORMANCE); - break; - } - case 3: { - PWR_setCPUSpeed(CPU_SPEED_NORMAL); - useAutoCpu = 1; - break; - } - } +static void setOverclock(int i) +{ + overclock = i; + switch (i) { + case 0: { + useAutoCpu = 0; + PWR_setCPUSpeed(CPU_SPEED_POWERSAVE); + break; + } + case 1: { + useAutoCpu = 0; + PWR_setCPUSpeed(CPU_SPEED_NORMAL); + break; + } + case 2: { + useAutoCpu = 0; + PWR_setCPUSpeed(CPU_SPEED_PERFORMANCE); + break; + } + case 3: { + PWR_setCPUSpeed(CPU_SPEED_NORMAL); + useAutoCpu = 1; + break; + } + } } static int toggle_thread = 0; static int shadersreload = 0; -static void Config_syncFrontend(char* key, int value) { +static void Config_syncFrontend(char *key, int value) +{ int i = -1; - if (exactMatch(key,config.frontend.options[FE_OPT_SCALING].key)) { - screen_scaling = value; - + if (exactMatch(key, config.frontend.options[FE_OPT_SCALING].key)) { + screen_scaling = value; + renderer.dst_p = 0; i = FE_OPT_SCALING; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_RESAMPLING].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_RESAMPLING].key)) { resampling_quality = value; SND_setQuality(resampling_quality); i = FE_OPT_RESAMPLING; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_AMBIENT].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_AMBIENT].key)) { ambient_mode = value; - if(ambient_mode > 0) + if (ambient_mode > 0) LEDS_pushProfileOverride(LIGHT_PROFILE_AMBIENT); - else + else LEDS_popProfileOverride(LIGHT_PROFILE_AMBIENT); i = FE_OPT_AMBIENT; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_EFFECT].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_EFFECT].key)) { screen_effect = value; GFX_setEffect(value); renderer.dst_p = 0; i = FE_OPT_EFFECT; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_OVERLAY].key)) { - char** overlayList = config.frontend.options[FE_OPT_OVERLAY].values; + } else if (exactMatch(key, config.frontend.options[FE_OPT_OVERLAY].key)) { + char **overlayList = config.frontend.options[FE_OPT_OVERLAY].values; if (overlayList) { - int count = 0; - while (overlayList && overlayList[count]) count++; + while (overlayList && overlayList[count]) + count++; if (value >= 0 && value < count) { LOG_info("minarch: updating overlay - %s\n", overlayList[value]); GFX_setOverlay(overlayList[value], core.tag); @@ -2037,130 +1931,127 @@ static void Config_syncFrontend(char* key, int value) { i = FE_OPT_OVERLAY; } } - } - else if (exactMatch(key,config.frontend.options[FE_OPT_SCREENX].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_SCREENX].key)) { screenx = value; GFX_setOffsetX(value); i = FE_OPT_SCREENX; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_SCREENY].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_SCREENY].key)) { screeny = value; GFX_setOffsetY(value); i = FE_OPT_SCREENY; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_SHARPNESS].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_SHARPNESS].key)) { GFX_setSharpness(value); i = FE_OPT_SHARPNESS; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_TEARING].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_TEARING].key)) { prevent_tearing = value; i = FE_OPT_TEARING; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_SYNC_REFERENCE].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_SYNC_REFERENCE].key)) { sync_ref = value; i = FE_OPT_SYNC_REFERENCE; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_OVERCLOCK].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_OVERCLOCK].key)) { overclock = value; i = FE_OPT_OVERCLOCK; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_DEBUG].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_DEBUG].key)) { show_debug = value; i = FE_OPT_DEBUG; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_MAXFF].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_MAXFF].key)) { max_ff_speed = value; i = FE_OPT_MAXFF; - } - else if (exactMatch(key,config.frontend.options[FE_OPT_FF_AUDIO].key)) { + } else if (exactMatch(key, config.frontend.options[FE_OPT_FF_AUDIO].key)) { ff_audio = value; i = FE_OPT_FF_AUDIO; } - if (i==-1) return; - Option* option = &config.frontend.options[i]; + if (i == -1) + return; + Option *option = &config.frontend.options[i]; option->value = value; } -char** list_files_in_folder(const char* folderPath, int* fileCount, const char* extensionFilter) { - DIR* dir = opendir(folderPath); - if (!dir) { - perror("opendir"); - return NULL; - } - - struct dirent* entry; - struct stat fileStat; - char** fileList = NULL; - *fileCount = 0; - - while ((entry = readdir(dir)) != NULL) { - char fullPath[1024]; - snprintf(fullPath, sizeof(fullPath), "%s/%s", folderPath, entry->d_name); - - if (stat(fullPath, &fileStat) == 0 && S_ISREG(fileStat.st_mode)) { - if (extensionFilter) { - const char* ext = strrchr(entry->d_name, '.'); - if (!ext || strcmp(ext, extensionFilter) != 0) { - continue; - } - } - - char** temp = realloc(fileList, sizeof(char*) * (*fileCount + 2)); - if (!temp) { - perror("realloc"); - for (int i = 0; i < *fileCount; ++i) { - free(fileList[i]); - } - free(fileList); - closedir(dir); - return NULL; - } - fileList = temp; - fileList[*fileCount] = strdup(entry->d_name); - fileList[*fileCount + 1] = NULL; - (*fileCount)++; - } - } - - closedir(dir); - - // Alphabetical sort - for (int i = 0; i < *fileCount - 1; ++i) { - for (int j = i + 1; j < *fileCount; ++j) { - if (strcmp(fileList[i], fileList[j]) > 0) { - char* temp = fileList[i]; - fileList[i] = fileList[j]; - fileList[j] = temp; - } - } - } - - return fileList; -} - - - - -static void OptionList_setOptionValue(OptionList* list, const char* key, const char* value); +char **list_files_in_folder(const char *folderPath, int *fileCount, const char *extensionFilter) +{ + DIR *dir = opendir(folderPath); + if (!dir) { + perror("opendir"); + return NULL; + } + + struct dirent *entry; + struct stat fileStat; + char **fileList = NULL; + *fileCount = 0; + + while ((entry = readdir(dir)) != NULL) { + char fullPath[1024]; + snprintf(fullPath, sizeof(fullPath), "%s/%s", folderPath, entry->d_name); + + if (stat(fullPath, &fileStat) == 0 && S_ISREG(fileStat.st_mode)) { + if (extensionFilter) { + const char *ext = strrchr(entry->d_name, '.'); + if (!ext || strcmp(ext, extensionFilter) != 0) { + continue; + } + } + + char **temp = realloc(fileList, sizeof(char *) * (*fileCount + 2)); + if (!temp) { + perror("realloc"); + for (int i = 0; i < *fileCount; ++i) { + free(fileList[i]); + } + free(fileList); + closedir(dir); + return NULL; + } + fileList = temp; + fileList[*fileCount] = strdup(entry->d_name); + fileList[*fileCount + 1] = NULL; + (*fileCount)++; + } + } + + closedir(dir); + + // Alphabetical sort + for (int i = 0; i < *fileCount - 1; ++i) { + for (int j = i + 1; j < *fileCount; ++j) { + if (strcmp(fileList[i], fileList[j]) > 0) { + char *temp = fileList[i]; + fileList[i] = fileList[j]; + fileList[j] = temp; + } + } + } + + return fileList; +} + + +static void OptionList_setOptionValue(OptionList *list, const char *key, const char *value); enum { CONFIG_WRITE_ALL, CONFIG_WRITE_GAME, }; -static void Config_getPath(char* filename, int override) { +static void Config_getPath(char *filename, int override) +{ char device_tag[64] = {0}; - if (config.device_tag) sprintf(device_tag,"-%s",config.device_tag); - if (override) sprintf(filename, "%s/%s%s.cfg", core.config_dir, game.alt_name, device_tag); - else sprintf(filename, "%s/minarch%s.cfg", core.config_dir, device_tag); + if (config.device_tag) + sprintf(device_tag, "-%s", config.device_tag); + if (override) + sprintf(filename, "%s/%s%s.cfg", core.config_dir, game.alt_name, device_tag); + else + sprintf(filename, "%s/minarch%s.cfg", core.config_dir, device_tag); LOG_info("Config_getPath %s\n", filename); } -static void Config_init(void) { - if (!config.default_cfg || config.initialized) return; - +static void Config_init(void) +{ + if (!config.default_cfg || config.initialized) + return; + LOG_info("Config_init\n"); - char* tmp = config.default_cfg; - char* tmp2; - char* key; - + char *tmp = config.default_cfg; + char *tmp2; + char *key; + char button_name[128]; char button_id[128]; int i = 0; @@ -2168,61 +2059,65 @@ static void Config_init(void) { tmp += 5; // tmp now points to the button name (plus the rest of the line) key = tmp; tmp = strstr(tmp, " = "); - if (!tmp) break; - - int len = tmp-key; + if (!tmp) + break; + + int len = tmp - key; strncpy(button_name, key, len); button_name[len] = '\0'; - + tmp += 3; strncpy(button_id, tmp, 128); tmp2 = strchr(button_id, '\n'); - if (!tmp2) tmp2 = strchr(button_id, '\r'); - if (tmp2) *tmp2 = '\0'; - + if (!tmp2) + tmp2 = strchr(button_id, '\r'); + if (tmp2) + *tmp2 = '\0'; + int retro_id = -1; int local_id = -1; - + tmp2 = strrchr(button_id, ':'); int remap = 0; if (tmp2) { - for (int j=0; button_label_mapping[j].name; j++) { - ButtonMapping* button = &button_label_mapping[j]; - if (!strcmp(tmp2+1,button->name)) { + for (int j = 0; button_label_mapping[j].name; j++) { + ButtonMapping *button = &button_label_mapping[j]; + if (!strcmp(tmp2 + 1, button->name)) { retro_id = button->retro; break; } } *tmp2 = '\0'; } - for (int j=0; button_label_mapping[j].name; j++) { - ButtonMapping* button = &button_label_mapping[j]; - if (!strcmp(button_id,button->name)) { + for (int j = 0; button_label_mapping[j].name; j++) { + ButtonMapping *button = &button_label_mapping[j]; + if (!strcmp(button_id, button->name)) { local_id = button->local; - if (retro_id==-1) retro_id = button->retro; + if (retro_id == -1) + retro_id = button->retro; break; } } - + tmp += strlen(button_id); // prepare to continue search - + LOG_info("\tbind %s (%s) %i:%i\n", button_name, button_id, local_id, retro_id); - + // TODO: test this without a final line return - tmp2 = calloc(strlen(button_name)+1, sizeof(char)); + tmp2 = calloc(strlen(button_name) + 1, sizeof(char)); strcpy(tmp2, button_name); - ButtonMapping* button = &core_button_mapping[i++]; + ButtonMapping *button = &core_button_mapping[i++]; button->name = tmp2; button->retro = retro_id; button->local = local_id; }; - + // populate shader options int filecount; - char** filelist = list_files_in_folder(SHADERS_FOLDER "/glsl", &filecount,NULL); + char **filelist = list_files_in_folder(SHADERS_FOLDER "/glsl", &filecount, NULL); int preset_filecount; - char** preset_filelist = list_files_in_folder(SHADERS_FOLDER, &preset_filecount,".cfg"); - + char **preset_filelist = list_files_in_folder(SHADERS_FOLDER, &preset_filecount, ".cfg"); + config.shaders.options[SH_SHADER1].values = filelist; config.shaders.options[SH_SHADER2].values = filelist; config.shaders.options[SH_SHADER3].values = filelist; @@ -2237,14 +2132,14 @@ static void Config_init(void) { config.shaders.options[SH_SHADER2].count = filecount; config.shaders.options[SH_SHADER3].count = filecount; config.shaders.options[SH_SHADERS_PRESET].count = preset_filecount; - + char overlaypath[255]; snprintf(overlaypath, sizeof(overlaypath), "%s/%s", OVERLAYS_FOLDER, core.tag); - char** overlaylist = list_files_in_folder(overlaypath, &filecount,NULL); + char **overlaylist = list_files_in_folder(overlaypath, &filecount, NULL); if (overlaylist) { int newcount = filecount + 1; - char** newlist = malloc(sizeof(char*) * (newcount + 1)); // +1 for NULL terminator + char **newlist = malloc(sizeof(char *) * (newcount + 1)); // +1 for NULL terminator if (!newlist) { LOG_info("failed to make newlist"); return; @@ -2253,9 +2148,9 @@ static void Config_init(void) { newlist[i + 1] = overlaylist[i]; } - newlist[0] = strdup("None"); - newlist[newcount] = NULL; - + newlist[0] = strdup("None"); + newlist[newcount] = NULL; + free(overlaylist); overlaylist = newlist; @@ -2267,103 +2162,116 @@ static void Config_init(void) { } config.initialized = 1; } -static void Config_quit(void) { - if (!config.initialized) return; - for (int i=0; core_button_mapping[i].name; i++) { +static void Config_quit(void) +{ + if (!config.initialized) + return; + for (int i = 0; core_button_mapping[i].name; i++) { free(core_button_mapping[i].name); } } -static void Config_readOptionsString(char* cfg) { - if (!cfg) return; +static void Config_readOptionsString(char *cfg) +{ + if (!cfg) + return; LOG_info("Config_readOptions\n"); char key[256]; char value[256]; - for (int i=0; config.frontend.options[i].key; i++) { - Option* option = &config.frontend.options[i]; - if (!Config_getValue(cfg, option->key, value, &option->lock)) continue; + for (int i = 0; config.frontend.options[i].key; i++) { + Option *option = &config.frontend.options[i]; + if (!Config_getValue(cfg, option->key, value, &option->lock)) + continue; OptionList_setOptionValue(&config.frontend, option->key, value); Config_syncFrontend(option->key, option->value); } - - if (has_custom_controllers && Config_getValue(cfg,"minarch_gamepad_type",value,NULL)) { + + if (has_custom_controllers && Config_getValue(cfg, "minarch_gamepad_type", value, NULL)) { gamepad_type = strtol(value, NULL, 0); int device = strtol(gamepad_values[gamepad_type], NULL, 0); core.set_controller_port_device(0, device); } - for (int i=0; config.core.options[i].key; i++) { - Option* option = &config.core.options[i]; + for (int i = 0; config.core.options[i].key; i++) { + Option *option = &config.core.options[i]; // LOG_info("%s\n",option->key); - if (!Config_getValue(cfg, option->key, value, &option->lock)) continue; + if (!Config_getValue(cfg, option->key, value, &option->lock)) + continue; OptionList_setOptionValue(&config.core, option->key, value); } - for (int i=0; config.shaders.options[i].key; i++) { - Option* option = &config.shaders.options[i]; - if (!Config_getValue(cfg, option->key, value, &option->lock)) continue; + for (int i = 0; config.shaders.options[i].key; i++) { + Option *option = &config.shaders.options[i]; + if (!Config_getValue(cfg, option->key, value, &option->lock)) + continue; OptionList_setOptionValue(&config.shaders, option->key, value); } - for (int y=0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { - if(config.shaderpragmas[y].count > 0) { - for (int i=0; config.shaderpragmas[y].options[i].key; i++) { - Option* option = &config.shaderpragmas[y].options[i]; - if (!Config_getValue(cfg, option->key, value, &option->lock)) continue; + for (int y = 0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { + if (config.shaderpragmas[y].count > 0) { + for (int i = 0; config.shaderpragmas[y].options[i].key; i++) { + Option *option = &config.shaderpragmas[y].options[i]; + if (!Config_getValue(cfg, option->key, value, &option->lock)) + continue; OptionList_setOptionValue(&config.shaderpragmas[y], option->key, value); } } } } -static void Config_readControlsString(char* cfg) { - if (!cfg) return; +static void Config_readControlsString(char *cfg) +{ + if (!cfg) + return; LOG_info("Config_readControlsString\n"); - + char key[256]; char value[256]; - char* tmp; - for (int i=0; config.controls[i].name; i++) { - ButtonMapping* mapping = &config.controls[i]; + char *tmp; + for (int i = 0; config.controls[i].name; i++) { + ButtonMapping *mapping = &config.controls[i]; sprintf(key, "bind %s", mapping->name); sprintf(value, "NONE"); - - if (!Config_getValue(cfg, key, value, NULL)) continue; - if ((tmp = strrchr(value, ':'))) *tmp = '\0'; // this is a binding artifact in default.cfg, ignore - + + if (!Config_getValue(cfg, key, value, NULL)) + continue; + if ((tmp = strrchr(value, ':'))) + *tmp = '\0'; // this is a binding artifact in default.cfg, ignore + int id = -1; - for (int j=0; button_labels[j]; j++) { - if (!strcmp(button_labels[j],value)) { + for (int j = 0; button_labels[j]; j++) { + if (!strcmp(button_labels[j], value)) { id = j - 1; break; } } // LOG_info("\t%s (%i)\n", value, id); - + int mod = 0; - if (id>=LOCAL_BUTTON_COUNT) { + if (id >= LOCAL_BUTTON_COUNT) { id -= LOCAL_BUTTON_COUNT; mod = 1; } - + mapping->local = id; mapping->mod = mod; } - - for (int i=0; config.shortcuts[i].name; i++) { - ButtonMapping* mapping = &config.shortcuts[i]; + + for (int i = 0; config.shortcuts[i].name; i++) { + ButtonMapping *mapping = &config.shortcuts[i]; sprintf(key, "bind %s", mapping->name); sprintf(value, "NONE"); - if (!Config_getValue(cfg, key, value, NULL)) continue; - + if (!Config_getValue(cfg, key, value, NULL)) + continue; + int id = -1; - for (int j=0; button_labels[j]; j++) { - if (!strcmp(button_labels[j],value)) { + for (int j = 0; button_labels[j]; j++) { + if (!strcmp(button_labels[j], value)) { id = j - 1; break; } } - + int mod = 0; - if (id>=LOCAL_BUTTON_COUNT) { + if (id >= LOCAL_BUTTON_COUNT) { id -= LOCAL_BUTTON_COUNT; mod = 1; } @@ -2373,225 +2281,249 @@ static void Config_readControlsString(char* cfg) { mapping->mod = mod; } } -static void Config_load(void) { +static void Config_load(void) +{ LOG_info("Config_load\n"); - + config.device_tag = getenv("DEVICE"); LOG_info("config.device_tag %s\n", config.device_tag); - + // update for crop overscan support - Option* scaling_option = &config.frontend.options[FE_OPT_SCALING]; + Option *scaling_option = &config.frontend.options[FE_OPT_SCALING]; scaling_option->desc = getScreenScalingDesc(); scaling_option->count = getScreenScalingCount(); if (!GFX_supportsOverscan()) { scaling_labels[4] = NULL; } - - char* system_path = SYSTEM_PATH "/system.cfg"; - + + char *system_path = SYSTEM_PATH "/system.cfg"; + char device_system_path[MAX_PATH] = {0}; - if (config.device_tag) sprintf(device_system_path, SYSTEM_PATH "/system-%s.cfg", config.device_tag); - + if (config.device_tag) + sprintf(device_system_path, SYSTEM_PATH "/system-%s.cfg", config.device_tag); + if (config.device_tag && exists(device_system_path)) { LOG_info("usng device_system_path: %s\n", device_system_path); config.system_cfg = allocFile(device_system_path); - } - else if (exists(system_path)) config.system_cfg = allocFile(system_path); - else config.system_cfg = NULL; - - - + } else if (exists(system_path)) + config.system_cfg = allocFile(system_path); + else + config.system_cfg = NULL; + + // LOG_info("config.system_cfg: %s\n", config.system_cfg); - + char default_path[MAX_PATH]; getEmuPath((char *)core.tag, default_path); - char* tmp = strrchr(default_path, '/'); - strcpy(tmp,"/default.cfg"); + char *tmp = strrchr(default_path, '/'); + strcpy(tmp, "/default.cfg"); char device_default_path[MAX_PATH] = {0}; if (config.device_tag) { getEmuPath((char *)core.tag, device_default_path); tmp = strrchr(device_default_path, '/'); char filename[64]; - sprintf(filename,"/default-%s.cfg", config.device_tag); - strcpy(tmp,filename); + sprintf(filename, "/default-%s.cfg", config.device_tag); + strcpy(tmp, filename); } - + if (config.device_tag && exists(device_default_path)) { LOG_info("usng device_default_path: %s\n", device_default_path); config.default_cfg = allocFile(device_default_path); - } - else if (exists(default_path)) config.default_cfg = allocFile(default_path); - else config.default_cfg = NULL; - + } else if (exists(default_path)) + config.default_cfg = allocFile(default_path); + else + config.default_cfg = NULL; + // LOG_info("config.default_cfg: %s\n", config.default_cfg); - + char path[MAX_PATH]; config.loaded = CONFIG_NONE; int override = 0; Config_getPath(path, CONFIG_WRITE_GAME); - if (exists(path)) override = 1; - if (!override) Config_getPath(path, CONFIG_WRITE_ALL); - + if (exists(path)) + override = 1; + if (!override) + Config_getPath(path, CONFIG_WRITE_ALL); + config.user_cfg = allocFile(path); - if (!config.user_cfg) return; - + if (!config.user_cfg) + return; + LOG_info("using user config: %s\n", path); - + config.loaded = override ? CONFIG_GAME : CONFIG_CONSOLE; } -static void Config_free(void) { - if (config.system_cfg) free(config.system_cfg); - if (config.default_cfg) free(config.default_cfg); - if (config.user_cfg) free(config.user_cfg); -} -static void Config_readOptions(void) { +static void Config_free(void) +{ + if (config.system_cfg) + free(config.system_cfg); + if (config.default_cfg) + free(config.default_cfg); + if (config.user_cfg) + free(config.user_cfg); +} +static void Config_readOptions(void) +{ Config_readOptionsString(config.system_cfg); Config_readOptionsString(config.default_cfg); Config_readOptionsString(config.user_cfg); } -static void Config_readControls(void) { +static void Config_readControls(void) +{ Config_readControlsString(config.default_cfg); Config_readControlsString(config.user_cfg); } -static void Config_write(int override) { +static void Config_write(int override) +{ char path[MAX_PATH]; // sprintf(path, "%s/%s.cfg", core.config_dir, game.alt_name); Config_getPath(path, CONFIG_WRITE_GAME); - + if (!override) { - if (config.loaded==CONFIG_GAME) unlink(path); + if (config.loaded == CONFIG_GAME) + unlink(path); Config_getPath(path, CONFIG_WRITE_ALL); } config.loaded = override ? CONFIG_GAME : CONFIG_CONSOLE; - + FILE *file = fopen(path, "wb"); - if (!file) return; - - for (int i=0; config.frontend.options[i].key; i++) { - Option* option = &config.frontend.options[i]; + if (!file) + return; + + for (int i = 0; config.frontend.options[i].key; i++) { + Option *option = &config.frontend.options[i]; int count = 0; - while ( option->values && option->values[count]) count++; + while (option->values && option->values[count]) + count++; if (option->value >= 0 && option->value < count) { fprintf(file, "%s = %s\n", option->key, option->values[option->value]); } } - for (int i=0; config.core.options[i].key; i++) { - Option* option = &config.core.options[i]; + for (int i = 0; config.core.options[i].key; i++) { + Option *option = &config.core.options[i]; fprintf(file, "%s = %s\n", option->key, option->values[option->value]); } - for (int i=0; config.shaders.options[i].key; i++) { - Option* option = &config.shaders.options[i]; + for (int i = 0; config.shaders.options[i].key; i++) { + Option *option = &config.shaders.options[i]; int count = 0; - while ( option->values && option->values[count]) count++; + while (option->values && option->values[count]) + count++; if (option->value >= 0 && option->value < count) { fprintf(file, "%s = %s\n", option->key, option->values[option->value]); } } - for (int y=0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { - for (int i=0; config.shaderpragmas[y].options[i].key; i++) { - Option* option = &config.shaderpragmas[y].options[i]; + for (int y = 0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { + for (int i = 0; config.shaderpragmas[y].options[i].key; i++) { + Option *option = &config.shaderpragmas[y].options[i]; int count = 0; - while ( option->values && option->values[count]) count++; + while (option->values && option->values[count]) + count++; if (option->value >= 0 && option->value < count) { fprintf(file, "%s = %s\n", option->key, option->values[option->value]); } } } - - if (has_custom_controllers) fprintf(file, "%s = %i\n", "minarch_gamepad_type", gamepad_type); - - for (int i=0; config.controls[i].name; i++) { - ButtonMapping* mapping = &config.controls[i]; + + if (has_custom_controllers) + fprintf(file, "%s = %i\n", "minarch_gamepad_type", gamepad_type); + + for (int i = 0; config.controls[i].name; i++) { + ButtonMapping *mapping = &config.controls[i]; int j = mapping->local + 1; - if (mapping->mod) j += LOCAL_BUTTON_COUNT; + if (mapping->mod) + j += LOCAL_BUTTON_COUNT; fprintf(file, "bind %s = %s\n", mapping->name, button_labels[j]); } - for (int i=0; config.shortcuts[i].name; i++) { - ButtonMapping* mapping = &config.shortcuts[i]; + for (int i = 0; config.shortcuts[i].name; i++) { + ButtonMapping *mapping = &config.shortcuts[i]; int j = mapping->local + 1; - if (mapping->mod) j += LOCAL_BUTTON_COUNT; + if (mapping->mod) + j += LOCAL_BUTTON_COUNT; fprintf(file, "bind %s = %s\n", mapping->name, button_labels[j]); } - + fclose(file); sync(); } -static void Config_restore(void) { +static void Config_restore(void) +{ char path[MAX_PATH]; - if (config.loaded==CONFIG_GAME) { - if (config.device_tag) sprintf(path, "%s/%s-%s.cfg", core.config_dir, game.alt_name, config.device_tag); - else sprintf(path, "%s/%s.cfg", core.config_dir, game.alt_name); + if (config.loaded == CONFIG_GAME) { + if (config.device_tag) + sprintf(path, "%s/%s-%s.cfg", core.config_dir, game.alt_name, config.device_tag); + else + sprintf(path, "%s/%s.cfg", core.config_dir, game.alt_name); unlink(path); LOG_info("deleted game config: %s\n", path); - } - else if (config.loaded==CONFIG_CONSOLE) { - if (config.device_tag) sprintf(path, "%s/minarch-%s.cfg", core.config_dir, config.device_tag); - else sprintf(path, "%s/minarch.cfg", core.config_dir); + } else if (config.loaded == CONFIG_CONSOLE) { + if (config.device_tag) + sprintf(path, "%s/minarch-%s.cfg", core.config_dir, config.device_tag); + else + sprintf(path, "%s/minarch.cfg", core.config_dir); unlink(path); LOG_info("deleted console config: %s\n", path); } config.loaded = CONFIG_NONE; - - for (int i=0; config.frontend.options[i].key; i++) { - Option* option = &config.frontend.options[i]; + + for (int i = 0; config.frontend.options[i].key; i++) { + Option *option = &config.frontend.options[i]; option->value = option->default_value; Config_syncFrontend(option->key, option->value); } - for (int i=0; config.core.options[i].key; i++) { - Option* option = &config.core.options[i]; + for (int i = 0; config.core.options[i].key; i++) { + Option *option = &config.core.options[i]; option->value = option->default_value; } - for (int i=0; config.shaders.options[i].key; i++) { - Option* option = &config.shaders.options[i]; + for (int i = 0; config.shaders.options[i].key; i++) { + Option *option = &config.shaders.options[i]; option->value = option->default_value; } config.core.changed = 1; // let the core know - + if (has_custom_controllers) { gamepad_type = 0; core.set_controller_port_device(0, RETRO_DEVICE_JOYPAD); } - for (int i=0; config.controls[i].name; i++) { - ButtonMapping* mapping = &config.controls[i]; + for (int i = 0; config.controls[i].name; i++) { + ButtonMapping *mapping = &config.controls[i]; mapping->local = mapping->default_; mapping->mod = 0; } - for (int i=0; config.shortcuts[i].name; i++) { - ButtonMapping* mapping = &config.shortcuts[i]; + for (int i = 0; config.shortcuts[i].name; i++) { + ButtonMapping *mapping = &config.shortcuts[i]; mapping->local = BTN_ID_NONE; mapping->mod = 0; } - + Config_load(); Config_readOptions(); Config_readControls(); Config_free(); - + renderer.dst_p = 0; } -void readShadersPreset(int i) { - char shaderspath[MAX_PATH] = {0}; - sprintf(shaderspath, SHADERS_FOLDER "/%s", config.shaders.options[SH_SHADERS_PRESET].values[i]); - LOG_info("read shaders preset %s\n",shaderspath); - if (exists(shaderspath)) { - config.shaders_preset = allocFile(shaderspath); - Config_readOptionsString(config.shaders_preset); - } - else config.shaders_preset = NULL; - - - -} -void loadShaderSettings(int i) { +void readShadersPreset(int i) +{ + char shaderspath[MAX_PATH] = {0}; + sprintf(shaderspath, SHADERS_FOLDER "/%s", config.shaders.options[SH_SHADERS_PRESET].values[i]); + LOG_info("read shaders preset %s\n", shaderspath); + if (exists(shaderspath)) { + config.shaders_preset = allocFile(shaderspath); + Config_readOptionsString(config.shaders_preset); + } else + config.shaders_preset = NULL; +} +void loadShaderSettings(int i) +{ int menucount = 0; config.shaderpragmas[i].options = calloc(32 + 1, sizeof(Option)); ShaderParam *params = PLAT_getShaderPragmas(i); - if(params == NULL) return; + if (params == NULL) + return; for (int j = 0; j < 32; j++) { - if (params[j].step == 0.0f) { // Prevent division by zero; skip this parameter or set steps to 1 continue; @@ -2605,7 +2537,7 @@ void loadShaderSettings(int i) { config.shaderpragmas[i].options[menucount].name = params[j].name; config.shaderpragmas[i].options[menucount].desc = params[j].name; config.shaderpragmas[i].options[menucount].default_value = params[j].def; - + int steps = (int)((params[j].max - params[j].min) / params[j].step) + 1; config.shaderpragmas[i].options[menucount].values = malloc(sizeof(char *) * (steps + 1)); config.shaderpragmas[i].options[menucount].labels = malloc(sizeof(char *) * (steps + 1)); @@ -2622,138 +2554,146 @@ void loadShaderSettings(int i) { config.shaderpragmas[i].options[menucount].values[steps] = NULL; config.shaderpragmas[i].options[menucount].labels[steps] = NULL; menucount++; - } config.shaderpragmas[i].count = menucount; } -static void Config_syncShaders(char* key, int value) { +static void Config_syncShaders(char *key, int value) +{ int i = -1; - if (exactMatch(key,config.shaders.options[SH_SHADERS_PRESET].key)) { + if (exactMatch(key, config.shaders.options[SH_SHADERS_PRESET].key)) { readShadersPreset(value); i = SH_SHADERS_PRESET; } - if (exactMatch(key,config.shaders.options[SH_NROFSHADERS].key)) { + if (exactMatch(key, config.shaders.options[SH_NROFSHADERS].key)) { GFX_setShaders(value); shadersreload = 1; i = SH_NROFSHADERS; } if (exactMatch(key, config.shaders.options[SH_SHADER1].key)) { - char** shaderList = config.shaders.options[SH_SHADER1].values; + char **shaderList = config.shaders.options[SH_SHADER1].values; if (shaderList) { - LOG_info("minarch: updating shader 1 - %i\n",value); + LOG_info("minarch: updating shader 1 - %i\n", value); int count = 0; - while (shaderList && shaderList[count]) count++; + while (shaderList && shaderList[count]) + count++; if (value >= 0 && value < count) { - GFX_updateShader(0, shaderList[value], NULL, NULL,NULL,NULL); + GFX_updateShader(0, shaderList[value], NULL, NULL, NULL, NULL); i = SH_SHADER1; - } + } } loadShaderSettings(0); } - if (exactMatch(key,config.shaders.options[SH_SHADER1_FILTER].key)) { - GFX_updateShader(0,NULL,NULL,&value,NULL,NULL); + if (exactMatch(key, config.shaders.options[SH_SHADER1_FILTER].key)) { + GFX_updateShader(0, NULL, NULL, &value, NULL, NULL); i = SH_SHADER1_FILTER; } - if (exactMatch(key,config.shaders.options[SH_SRCTYPE1].key)) { - GFX_updateShader(0,NULL,NULL,NULL,NULL,&value); + if (exactMatch(key, config.shaders.options[SH_SRCTYPE1].key)) { + GFX_updateShader(0, NULL, NULL, NULL, NULL, &value); i = SH_SRCTYPE1; } - if (exactMatch(key,config.shaders.options[SH_SCALETYPE1].key)) { - GFX_updateShader(0,NULL,NULL,NULL,&value,NULL); + if (exactMatch(key, config.shaders.options[SH_SCALETYPE1].key)) { + GFX_updateShader(0, NULL, NULL, NULL, &value, NULL); i = SH_SCALETYPE1; } - if (exactMatch(key,config.shaders.options[SH_UPSCALE1].key)) { - GFX_updateShader(0,NULL,&value,NULL,NULL,NULL); + if (exactMatch(key, config.shaders.options[SH_UPSCALE1].key)) { + GFX_updateShader(0, NULL, &value, NULL, NULL, NULL); i = SH_UPSCALE1; } if (exactMatch(key, config.shaders.options[SH_SHADER2].key)) { - char** shaderList = config.shaders.options[SH_SHADER2].values; + char **shaderList = config.shaders.options[SH_SHADER2].values; if (shaderList) { - LOG_info("minarch: updating shader 2 - %i\n",value); + LOG_info("minarch: updating shader 2 - %i\n", value); int count = 0; - while (shaderList && shaderList[count]) count++; + while (shaderList && shaderList[count]) + count++; if (value >= 0 && value < count) { - GFX_updateShader(1, shaderList[value], NULL, NULL,NULL,NULL); + GFX_updateShader(1, shaderList[value], NULL, NULL, NULL, NULL); i = SH_SHADER2; } } loadShaderSettings(1); } - if (exactMatch(key,config.shaders.options[SH_SHADER2_FILTER].key)) { - GFX_updateShader(1,NULL,NULL,&value,NULL,NULL); + if (exactMatch(key, config.shaders.options[SH_SHADER2_FILTER].key)) { + GFX_updateShader(1, NULL, NULL, &value, NULL, NULL); i = SH_SHADER2_FILTER; } - if (exactMatch(key,config.shaders.options[SH_SRCTYPE2].key)) { - GFX_updateShader(1,NULL,NULL,NULL,NULL,&value); + if (exactMatch(key, config.shaders.options[SH_SRCTYPE2].key)) { + GFX_updateShader(1, NULL, NULL, NULL, NULL, &value); i = SH_SRCTYPE2; } - if (exactMatch(key,config.shaders.options[SH_SCALETYPE2].key)) { - GFX_updateShader(1,NULL,NULL,NULL,&value,NULL); + if (exactMatch(key, config.shaders.options[SH_SCALETYPE2].key)) { + GFX_updateShader(1, NULL, NULL, NULL, &value, NULL); i = SH_SCALETYPE2; } - if (exactMatch(key,config.shaders.options[SH_UPSCALE2].key)) { - GFX_updateShader(1,NULL,&value,NULL,NULL,NULL); + if (exactMatch(key, config.shaders.options[SH_UPSCALE2].key)) { + GFX_updateShader(1, NULL, &value, NULL, NULL, NULL); i = SH_UPSCALE2; } if (exactMatch(key, config.shaders.options[SH_SHADER3].key)) { - char** shaderList = config.shaders.options[SH_SHADER3].values; + char **shaderList = config.shaders.options[SH_SHADER3].values; if (shaderList) { - LOG_info("minarch: updating shader 3 - %i\n",value); + LOG_info("minarch: updating shader 3 - %i\n", value); int count = 0; - while (shaderList && shaderList[count]) count++; + while (shaderList && shaderList[count]) + count++; if (value >= 0 && value < count) { - GFX_updateShader(2, shaderList[value], NULL, NULL,NULL,NULL); + GFX_updateShader(2, shaderList[value], NULL, NULL, NULL, NULL); i = SH_SHADER3; } } loadShaderSettings(2); } - if (exactMatch(key,config.shaders.options[SH_SHADER3_FILTER].key)) { - GFX_updateShader(2,NULL,NULL,&value,NULL,NULL); + if (exactMatch(key, config.shaders.options[SH_SHADER3_FILTER].key)) { + GFX_updateShader(2, NULL, NULL, &value, NULL, NULL); i = SH_SHADER3_FILTER; } - if (exactMatch(key,config.shaders.options[SH_SRCTYPE3].key)) { - GFX_updateShader(2,NULL,NULL,NULL,NULL,&value); + if (exactMatch(key, config.shaders.options[SH_SRCTYPE3].key)) { + GFX_updateShader(2, NULL, NULL, NULL, NULL, &value); i = SH_SRCTYPE3; } - if (exactMatch(key,config.shaders.options[SH_SCALETYPE3].key)) { - GFX_updateShader(2,NULL,NULL,NULL,&value,NULL); + if (exactMatch(key, config.shaders.options[SH_SCALETYPE3].key)) { + GFX_updateShader(2, NULL, NULL, NULL, &value, NULL); i = SH_SCALETYPE3; } - if (exactMatch(key,config.shaders.options[SH_UPSCALE3].key)) { - GFX_updateShader(2,NULL,&value,NULL,NULL,NULL); + if (exactMatch(key, config.shaders.options[SH_UPSCALE3].key)) { + GFX_updateShader(2, NULL, &value, NULL, NULL, NULL); i = SH_UPSCALE3; } - - if (i==-1) return; - Option* option = &config.shaders.options[i]; + + if (i == -1) + return; + Option *option = &config.shaders.options[i]; option->value = value; shadersreload = 1; } //////// -void applyShaderSettings() { - for (int y=0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { +void applyShaderSettings() +{ + for (int y = 0; y < config.shaders.options[SH_NROFSHADERS].value; y++) { ShaderParam *params = PLAT_getShaderPragmas(y); if (params == NULL) { break; } - for (int i=0; i < config.shaderpragmas[y].count; i++) { + for (int i = 0; i < config.shaderpragmas[y].count; i++) { for (int j = 0; j < 32; j++) { if (exactMatch(params[j].name, config.shaderpragmas[y].options[i].key)) { - params[j].value = strtof(config.shaderpragmas[y].options[i].values[config.shaderpragmas[y].options[i].value], NULL); + params[j].value = strtof( + config.shaderpragmas[y].options[i].values[config.shaderpragmas[y].options[i].value], NULL); } } } } } -void initShaders() { - for (int i=0; config.shaders.options[i].key; i++) { - if(i!=SH_SHADERS_PRESET) { - Option* option = &config.shaders.options[i];; +void initShaders() +{ + for (int i = 0; config.shaders.options[i].key; i++) { + if (i != SH_SHADERS_PRESET) { + Option *option = &config.shaders.options[i]; + ; Config_syncShaders(option->key, option->value); } } @@ -2764,87 +2704,100 @@ void initShaders() { static struct Special { int palette_updated; } special; -static void Special_updatedDMGPalette(int frames) { +static void Special_updatedDMGPalette(int frames) +{ // LOG_info("Special_updatedDMGPalette(%i)\n", frames); special.palette_updated = frames; // must wait a few frames } -static void Special_refreshDMGPalette(void) { +static void Special_refreshDMGPalette(void) +{ special.palette_updated -= 1; - if (special.palette_updated>0) return; - + if (special.palette_updated > 0) + return; + int rgb = getInt("/tmp/dmg_grid_color"); GFX_setEffectColor(rgb); } -static void Special_init(void) { - if (special.palette_updated>1) special.palette_updated = 1; +static void Special_init(void) +{ + if (special.palette_updated > 1) + special.palette_updated = 1; // else if (exactMatch((char*)core.tag, "GBC")) { // putInt("/tmp/dmg_grid_color",0xF79E); // special.palette_updated = 1; // } } -static void Special_render(void) { - if (special.palette_updated) Special_refreshDMGPalette(); +static void Special_render(void) +{ + if (special.palette_updated) + Special_refreshDMGPalette(); } -static void Special_quit(void) { +static void Special_quit(void) +{ system("rm -f /tmp/dmg_grid_color"); } /////////////////////////////// -static int Option_getValueIndex(Option* item, const char* value) { - if (!value || !item || !item->values) return 0; +static int Option_getValueIndex(Option *item, const char *value) +{ + if (!value || !item || !item->values) + return 0; int i = 0; while (item->values[i]) { - if (!strcmp(item->values[i], value)) return i; + if (!strcmp(item->values[i], value)) + return i; i++; } return 0; } -static void Option_setValue(Option* item, const char* value) { +static void Option_setValue(Option *item, const char *value) +{ // TODO: store previous value? item->value = Option_getValueIndex(item, value); } // TODO: does this also need to be applied to OptionList_vars()? -static const char* option_key_name[] = { - "pcsx_rearmed_analog_combo", "DualShock Toggle Combo", - NULL -}; -static const char* getOptionNameFromKey(const char* key, const char* name) { - char* _key = NULL; - for (int i=0; (_key = (char*)option_key_name[i]); i+=2) { - if (exactMatch((char*)key,_key)) return option_key_name[i+1]; +static const char *option_key_name[] = {"pcsx_rearmed_analog_combo", "DualShock Toggle Combo", NULL}; +static const char *getOptionNameFromKey(const char *key, const char *name) +{ + char *_key = NULL; + for (int i = 0; (_key = (char *)option_key_name[i]); i += 2) { + if (exactMatch((char *)key, _key)) + return option_key_name[i + 1]; } return name; } // the following 3 functions always touch config.core, the rest can operate on arbitrary OptionLists -static void OptionList_init(const struct retro_core_option_definition *defs) { +static void OptionList_init(const struct retro_core_option_definition *defs) +{ LOG_info("OptionList_init\n"); int count; - for (count=0; defs[count].key; count++); - + for (count = 0; defs[count].key; count++) + ; + // LOG_info("count: %i\n", count); - + // TODO: add frontend options to this? so the can use the same override method? eg. minarch_* config.core.count = count; config.core.categories = NULL; // There is no categories in v1 definition if (count) { - config.core.options = calloc(count+1, sizeof(Option)); - - for (int i=0; ikey) + 1; - + item->key = calloc(len, sizeof(char)); strcpy(item->key, def->key); - + len = strlen(def->desc) + 1; item->name = calloc(len, sizeof(char)); - strcpy(item->name, getOptionNameFromKey(def->key,def->desc)); - + strcpy(item->name, getOptionNameFromKey(def->key, def->desc)); + if (def->info) { len = strlen(def->info) + 1; item->desc = calloc(len, sizeof(char)); @@ -2853,176 +2806,184 @@ static void OptionList_init(const struct retro_core_option_definition *defs) { item->full = calloc(len, sizeof(char)); strncpy(item->full, item->desc, len); // item->desc[len-1] = '\0'; - - GFX_wrapText(font.tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); - GFX_wrapText(font.medium, item->full, DEVICE_WIDTH - SCALE1(2*PADDING), 16); + + GFX_wrapText(font.tiny, item->desc, DEVICE_WIDTH - SCALE1(2 * PADDING), 2); + GFX_wrapText(font.medium, item->full, DEVICE_WIDTH - SCALE1(2 * PADDING), 16); } - - for (count=0; def->values[count].value; count++); - + + for (count = 0; def->values[count].value; count++) + ; + item->count = count; - item->values = calloc(count+1, sizeof(char*)); - item->labels = calloc(count+1, sizeof(char*)); - - for (int j=0; jvalues[j].value; - const char* label = def->values[j].label; - + item->values = calloc(count + 1, sizeof(char *)); + item->labels = calloc(count + 1, sizeof(char *)); + + for (int j = 0; j < count; j++) { + const char *value = def->values[j].value; + const char *label = def->values[j].label; + len = strlen(value) + 1; item->values[j] = calloc(len, sizeof(char)); strcpy(item->values[j], value); - + if (label) { len = strlen(label) + 1; item->labels[j] = calloc(len, sizeof(char)); strcpy(item->labels[j], label); - } - else { + } else { item->labels[j] = item->values[j]; } // printf("\t%s\n", item->labels[j]); } - + item->value = Option_getValueIndex(item, def->default_value); item->default_value = item->value; - - // LOG_info("\tINIT %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], item->values[item->value]); + + // LOG_info("\tINIT %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], + // item->values[item->value]); } } // fflush(stdout); } -static void OptionList_v2_init(const struct retro_core_options_v2 *opt_defs) { +static void OptionList_v2_init(const struct retro_core_options_v2 *opt_defs) +{ LOG_info("OptionList_v2_init\n"); - struct retro_core_option_v2_category *cats = opt_defs->categories; + struct retro_core_option_v2_category *cats = opt_defs->categories; struct retro_core_option_v2_definition *defs = opt_defs->definitions; int cat_count = 0; - while (cats[cat_count].key) cat_count++; + while (cats[cat_count].key) + cat_count++; int count = 0; - while (defs[count].key) count++; - + while (defs[count].key) + count++; + // LOG_info("%i categories, %i options\n", cat_count, count); - + // TODO: add frontend options to this? so the can use the same override method? eg. minarch_* - + if (cat_count) { config.core.categories = calloc(cat_count + 1, sizeof(OptionCategory)); - for (int i=0; ikey = strdup(cat->key); + item->key = strdup(cat->key); item->desc = strdup(cat->desc); item->info = cat->info ? strdup(cat->info) : NULL; printf("CATEGORY %s\n", item->key); } - } - else { + } else { config.core.categories = NULL; } config.core.count = count; if (count) { - config.core.options = calloc(count+1, sizeof(Option)); - - for (int i=0; ikey = strdup(def->key); - item->name = strdup(getOptionNameFromKey(def->key, def->desc_categorized ? def->desc_categorized : def->desc)); + item->name = + strdup(getOptionNameFromKey(def->key, def->desc_categorized ? def->desc_categorized : def->desc)); item->category = def->category_key ? strdup(def->category_key) : NULL; if (def->info) { item->desc = strdup(def->info); item->full = strdup(item->desc); - - GFX_wrapText(font.tiny, item->desc, DEVICE_WIDTH - SCALE1(2*PADDING), 2); - GFX_wrapText(font.medium, item->full, DEVICE_WIDTH - SCALE1(2*PADDING), 16); + + GFX_wrapText(font.tiny, item->desc, DEVICE_WIDTH - SCALE1(2 * PADDING), 2); + GFX_wrapText(font.medium, item->full, DEVICE_WIDTH - SCALE1(2 * PADDING), 16); } - - for (count=0; def->values[count].value; count++); - + + for (count = 0; def->values[count].value; count++) + ; + item->count = count; - item->values = calloc(count+1, sizeof(char*)); - item->labels = calloc(count+1, sizeof(char*)); - - for (int j=0; jvalues[j].value; - const char* label = def->values[j].label; - + item->values = calloc(count + 1, sizeof(char *)); + item->labels = calloc(count + 1, sizeof(char *)); + + for (int j = 0; j < count; j++) { + const char *value = def->values[j].value; + const char *label = def->values[j].label; + item->values[j] = strdup(value); - + if (label) { item->labels[j] = strdup(label); - } - else { + } else { item->labels[j] = item->values[j]; } // printf("\t%s\n", item->labels[j]); } - + item->value = Option_getValueIndex(item, def->default_value); item->default_value = item->value; - - // LOG_info("\tINIT %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], item->values[item->value]); + + // LOG_info("\tINIT %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], + // item->values[item->value]); } } // fflush(stdout); } -static void OptionList_vars(const struct retro_variable *vars) { +static void OptionList_vars(const struct retro_variable *vars) +{ LOG_info("OptionList_vars\n"); int count; - for (count=0; vars[count].key; count++); - + for (count = 0; vars[count].key; count++) + ; + config.core.count = count; if (count) { - config.core.options = calloc(count+1, sizeof(Option)); - - for (int i=0; ikey) + 1; item->key = calloc(len, sizeof(char)); strcpy(item->key, var->key); - + len = strlen(var->value) + 1; item->var = calloc(len, sizeof(char)); strcpy(item->var, var->value); - - char* tmp = strchr(item->var, ';'); - if (tmp && *(tmp+1)==' ') { + + char *tmp = strchr(item->var, ';'); + if (tmp && *(tmp + 1) == ' ') { *tmp = '\0'; item->name = item->var; tmp += 2; } - - char* opt = tmp; - for (count=0; (tmp=strchr(tmp, '|')); tmp++, count++); + + char *opt = tmp; + for (count = 0; (tmp = strchr(tmp, '|')); tmp++, count++) + ; count += 1; // last entry after final '|' - + item->count = count; - item->values = calloc(count+1, sizeof(char*)); - item->labels = calloc(count+1, sizeof(char*)); + item->values = calloc(count + 1, sizeof(char *)); + item->labels = calloc(count + 1, sizeof(char *)); tmp = opt; int j; - for (j=0; (tmp=strchr(tmp, '|')); j++) { + for (j = 0; (tmp = strchr(tmp, '|')); j++) { item->values[j] = opt; item->labels[j] = opt; *tmp = '\0'; tmp += 1; - opt = tmp; + opt = tmp; } item->values[j] = opt; item->labels[j] = opt; - + // no native default_value support for retro vars item->value = 0; item->default_value = item->value; @@ -3031,23 +2992,27 @@ static void OptionList_vars(const struct retro_variable *vars) { } // fflush(stdout); } -static void OptionList_reset(void) { - if (!config.core.count) return; - - for (int i=0; ivar) { // values/labels are all points to var // so no need to free individually free(item->var); - } - else { - if (item->desc) free(item->desc); - if (item->full) free(item->full); - for (int j=0; jcount; j++) { - char* value = item->values[j]; - char* label = item->labels[j]; - if (label!=value) free(label); + } else { + if (item->desc) + free(item->desc); + if (item->full) + free(item->full); + for (int j = 0; j < item->count; j++) { + char *value = item->values[j]; + char *label = item->labels[j]; + if (label != value) + free(label); free(value); } } @@ -3056,24 +3021,30 @@ static void OptionList_reset(void) { free(item->key); free(item->name); } - if (config.core.enabled_options) free(config.core.enabled_options); + if (config.core.enabled_options) + free(config.core.enabled_options); config.core.enabled_count = 0; free(config.core.options); } -static Option* OptionList_getOption(OptionList* list, const char* key) { - for (int i=0; icount; i++) { - Option* item = &list->options[i]; - if (!strcmp(item->key, key)) return item; +static Option *OptionList_getOption(OptionList *list, const char *key) +{ + for (int i = 0; i < list->count; i++) { + Option *item = &list->options[i]; + if (!strcmp(item->key, key)) + return item; } return NULL; } -static char* OptionList_getOptionValue(OptionList* list, const char* key) { - Option* item = OptionList_getOption(list, key); - // if (item) LOG_info("\tGET %s (%s) = %s (%s)\n", item->name, item->key, item->labels[item->value], item->values[item->value]); +static char *OptionList_getOptionValue(OptionList *list, const char *key) +{ + Option *item = OptionList_getOption(list, key); + // if (item) LOG_info("\tGET %s (%s) = %s (%s)\n", item->name, item->key, item->labels[item->value], + // item->values[item->value]); if (item) { int count = 0; - while ( item->values && item->values[count]) count++; + while (item->values && item->values[count]) + count++; if (item->value >= 0 && item->value < count) { return item->values[item->value]; } @@ -3081,34 +3052,42 @@ static char* OptionList_getOptionValue(OptionList* list, const char* key) { // else LOG_warn("unknown option %s \n", key); return NULL; } -static void OptionList_setOptionRawValue(OptionList* list, const char* key, int value) { - Option* item = OptionList_getOption(list, key); +static void OptionList_setOptionRawValue(OptionList *list, const char *key, int value) +{ + Option *item = OptionList_getOption(list, key); if (item) { item->value = value; list->changed = 1; - // LOG_info("\tRAW SET %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], item->values[item->value]); - // if (list->on_set) list->on_set(list, key); + // LOG_info("\tRAW SET %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], + // item->values[item->value]); if (list->on_set) list->on_set(list, key); - if (exactMatch((char*)core.tag, "GB") && containsString(item->key, "palette")) Special_updatedDMGPalette(3); // from options - } - else LOG_info("unknown option %s \n", key); + if (exactMatch((char *)core.tag, "GB") && containsString(item->key, "palette")) + Special_updatedDMGPalette(3); // from options + } else + LOG_info("unknown option %s \n", key); } -static void OptionList_setOptionValue(OptionList* list, const char* key, const char* value) { - Option* item = OptionList_getOption(list, key); +static void OptionList_setOptionValue(OptionList *list, const char *key, const char *value) +{ + Option *item = OptionList_getOption(list, key); if (item) { Option_setValue(item, value); list->changed = 1; - // LOG_info("\tSET %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], item->values[item->value]); - // if (list->on_set) list->on_set(list, key); - - if (exactMatch((char*)core.tag, "GB") && containsString(item->key, "palette")) Special_updatedDMGPalette(2); // from core - } - else LOG_info("unknown option %s \n", key); + // LOG_info("\tSET %s (%s) TO %s (%s)\n", item->name, item->key, item->labels[item->value], + // item->values[item->value]); if (list->on_set) list->on_set(list, key); + + if (exactMatch((char *)core.tag, "GB") && containsString(item->key, "palette")) + Special_updatedDMGPalette(2); // from core + } else + LOG_info("unknown option %s \n", key); } -static void OptionList_setOptionVisibility(OptionList* list, const char* key, int visible) { - Option* item = OptionList_getOption(list, key); - if (item) item->hidden = !visible; - else printf("unknown option %s \n", key); fflush(stdout); +static void OptionList_setOptionVisibility(OptionList *list, const char *key, int visible) +{ + Option *item = OptionList_getOption(list, key); + if (item) + item->hidden = !visible; + else + printf("unknown option %s \n", key); + fflush(stdout); } /////////////////////////////// @@ -3121,14 +3100,16 @@ static void Menu_screenshot(void); static void Menu_saveState(void); static void Menu_loadState(void); -static int setFastForward(int enable) { +static int setFastForward(int enable) +{ fast_forward = enable; return enable; } static uint32_t buttons = 0; // RETRO_DEVICE_ID_JOYPAD_* buttons static int ignore_menu = 0; -static void input_poll_callback(void) { +static void input_poll_callback(void) +{ PAD_poll(); int show_setting = 0; @@ -3148,106 +3129,127 @@ static void input_poll_callback(void) { Menu_saveState(); putFile(GAME_SWITCHER_PERSIST_PATH, game.path + strlen(SDCARD_PATH)); GFX_clear(screen); - } - + if (PAD_justPressed(BTN_POWER)) { - - } - else if (PAD_justReleased(BTN_POWER)) { - + } else if (PAD_justReleased(BTN_POWER)) { } - + static int toggled_ff_on = 0; // this logic only works because TOGGLE_FF is before HOLD_FF in the menu... - for (int i=0; ilocal; - if (btn==BTN_NONE) continue; // not bound + if (btn == BTN_NONE) + continue; // not bound if (!mapping->mod || PAD_isPressed(BTN_MENU)) { - if (i==SHORTCUT_TOGGLE_FF) { + if (i == SHORTCUT_TOGGLE_FF) { if (PAD_justPressed(btn)) { toggled_ff_on = setFastForward(!fast_forward); - if (mapping->mod) ignore_menu = 1; + if (mapping->mod) + ignore_menu = 1; break; - } - else if (PAD_justReleased(btn)) { - if (mapping->mod) ignore_menu = 1; + } else if (PAD_justReleased(btn)) { + if (mapping->mod) + ignore_menu = 1; break; } - } - else if (i==SHORTCUT_HOLD_FF) { - // don't allow turn off fast_forward with a release of the hold button + } else if (i == SHORTCUT_HOLD_FF) { + // don't allow turn off fast_forward with a release of the hold button // if it was initially turned on with the toggle button if (PAD_justPressed(btn) || (!toggled_ff_on && PAD_justReleased(btn))) { fast_forward = setFastForward(PAD_isPressed(btn)); - if (mapping->mod) ignore_menu = 1; // very unlikely but just in case + if (mapping->mod) + ignore_menu = 1; // very unlikely but just in case } } // Trimui only - else if (PLAT_canTurbo() && i>=SHORTCUT_TOGGLE_TURBO_A && i<=SHORTCUT_TOGGLE_TURBO_R2) { + else if (PLAT_canTurbo() && i >= SHORTCUT_TOGGLE_TURBO_A && i <= SHORTCUT_TOGGLE_TURBO_R2) { if (PAD_justPressed(btn)) { - switch(i) { - case SHORTCUT_TOGGLE_TURBO_A: PLAT_toggleTurbo(BTN_ID_A); break; - case SHORTCUT_TOGGLE_TURBO_B: PLAT_toggleTurbo(BTN_ID_B); break; - case SHORTCUT_TOGGLE_TURBO_X: PLAT_toggleTurbo(BTN_ID_X); break; - case SHORTCUT_TOGGLE_TURBO_Y: PLAT_toggleTurbo(BTN_ID_Y); break; - case SHORTCUT_TOGGLE_TURBO_L: PLAT_toggleTurbo(BTN_ID_L1); break; - case SHORTCUT_TOGGLE_TURBO_L2: PLAT_toggleTurbo(BTN_ID_L2); break; - case SHORTCUT_TOGGLE_TURBO_R: PLAT_toggleTurbo(BTN_ID_R1); break; - case SHORTCUT_TOGGLE_TURBO_R2: PLAT_toggleTurbo(BTN_ID_R2); break; - default: break; - } - break; - } - else if (PAD_justReleased(btn)) { - break; - } - } - else if (PAD_justPressed(btn)) { - switch (i) { - case SHORTCUT_SAVE_STATE: - newScreenshot = 1; - Menu_saveState(); + switch (i) { + case SHORTCUT_TOGGLE_TURBO_A: + PLAT_toggleTurbo(BTN_ID_A); + break; + case SHORTCUT_TOGGLE_TURBO_B: + PLAT_toggleTurbo(BTN_ID_B); + break; + case SHORTCUT_TOGGLE_TURBO_X: + PLAT_toggleTurbo(BTN_ID_X); break; - case SHORTCUT_LOAD_STATE: Menu_loadState(); break; - case SHORTCUT_SCREENSHOT: - Menu_screenshot(); + case SHORTCUT_TOGGLE_TURBO_Y: + PLAT_toggleTurbo(BTN_ID_Y); break; - case SHORTCUT_RESET_GAME: core.reset(); break; - case SHORTCUT_SAVE_QUIT: - newScreenshot = 1; - quit = 1; - Menu_saveState(); + case SHORTCUT_TOGGLE_TURBO_L: + PLAT_toggleTurbo(BTN_ID_L1); break; - case SHORTCUT_GAMESWITCHER: - newScreenshot = 1; - quit = 1; - Menu_saveState(); - putFile(GAME_SWITCHER_PERSIST_PATH, game.path + strlen(SDCARD_PATH)); + case SHORTCUT_TOGGLE_TURBO_L2: + PLAT_toggleTurbo(BTN_ID_L2); break; - case SHORTCUT_CYCLE_SCALE: - screen_scaling += 1; - int count = config.frontend.options[FE_OPT_SCALING].count; - if (screen_scaling>=count) screen_scaling -= count; - Config_syncFrontend(config.frontend.options[FE_OPT_SCALING].key, screen_scaling); + case SHORTCUT_TOGGLE_TURBO_R: + PLAT_toggleTurbo(BTN_ID_R1); break; - case SHORTCUT_CYCLE_EFFECT: - screen_effect += 1; - if (screen_effect>=EFFECT_COUNT) screen_effect -= EFFECT_COUNT; - Config_syncFrontend(config.frontend.options[FE_OPT_EFFECT].key, screen_effect); + case SHORTCUT_TOGGLE_TURBO_R2: + PLAT_toggleTurbo(BTN_ID_R2); break; - default: break; + default: + break; + } + break; + } else if (PAD_justReleased(btn)) { + break; + } + } else if (PAD_justPressed(btn)) { + switch (i) { + case SHORTCUT_SAVE_STATE: + newScreenshot = 1; + Menu_saveState(); + break; + case SHORTCUT_LOAD_STATE: + Menu_loadState(); + break; + case SHORTCUT_SCREENSHOT: + Menu_screenshot(); + break; + case SHORTCUT_RESET_GAME: + core.reset(); + break; + case SHORTCUT_SAVE_QUIT: + newScreenshot = 1; + quit = 1; + Menu_saveState(); + break; + case SHORTCUT_GAMESWITCHER: + newScreenshot = 1; + quit = 1; + Menu_saveState(); + putFile(GAME_SWITCHER_PERSIST_PATH, game.path + strlen(SDCARD_PATH)); + break; + case SHORTCUT_CYCLE_SCALE: + screen_scaling += 1; + int count = config.frontend.options[FE_OPT_SCALING].count; + if (screen_scaling >= count) + screen_scaling -= count; + Config_syncFrontend(config.frontend.options[FE_OPT_SCALING].key, screen_scaling); + break; + case SHORTCUT_CYCLE_EFFECT: + screen_effect += 1; + if (screen_effect >= EFFECT_COUNT) + screen_effect -= EFFECT_COUNT; + Config_syncFrontend(config.frontend.options[FE_OPT_EFFECT].key, screen_effect); + break; + default: + break; } - - if (mapping->mod) ignore_menu = 1; + + if (mapping->mod) + ignore_menu = 1; } } } - + if (!ignore_menu && PAD_justReleased(BTN_MENU)) { show_menu = 1; } - + // TODO: figure out how to ignore button when MENU+button is handled first // TODO: array size of LOCAL_ whatever that macro is // TODO: then split it into two loops @@ -3256,93 +3258,111 @@ static void input_poll_callback(void) { // TODO: then check for button // TODO: only modify if absent from array // TODO: the shortcuts loop above should also contribute to the array - + buttons = 0; - for (int i=0; config.controls[i].name; i++) { - ButtonMapping* mapping = &config.controls[i]; + for (int i = 0; config.controls[i].name; i++) { + ButtonMapping *mapping = &config.controls[i]; int btn = 1 << mapping->local; - if (btn==BTN_NONE) continue; // present buttons can still be unbound - if (gamepad_type==0) { - switch(btn) { - case BTN_DPAD_UP: btn = BTN_UP; break; - case BTN_DPAD_DOWN: btn = BTN_DOWN; break; - case BTN_DPAD_LEFT: btn = BTN_LEFT; break; - case BTN_DPAD_RIGHT: btn = BTN_RIGHT; break; + if (btn == BTN_NONE) + continue; // present buttons can still be unbound + if (gamepad_type == 0) { + switch (btn) { + case BTN_DPAD_UP: + btn = BTN_UP; + break; + case BTN_DPAD_DOWN: + btn = BTN_DOWN; + break; + case BTN_DPAD_LEFT: + btn = BTN_LEFT; + break; + case BTN_DPAD_RIGHT: + btn = BTN_RIGHT; + break; } } if (PAD_isPressed(btn) && (!mapping->mod || PAD_isPressed(BTN_MENU))) { buttons |= 1 << mapping->retro; - if (mapping->mod) ignore_menu = 1; + if (mapping->mod) + ignore_menu = 1; } // && !PWR_ignoreSettingInput(btn, show_setting) } - + // if (buttons) LOG_info("buttons: %i\n", buttons); } -static int16_t input_state_callback(unsigned port, unsigned device, unsigned index, unsigned id) { - if (port==0 && device==RETRO_DEVICE_JOYPAD && index==0) { - if (id == RETRO_DEVICE_ID_JOYPAD_MASK) return buttons; +static int16_t input_state_callback(unsigned port, unsigned device, unsigned index, unsigned id) +{ + if (port == 0 && device == RETRO_DEVICE_JOYPAD && index == 0) { + if (id == RETRO_DEVICE_ID_JOYPAD_MASK) + return buttons; return (buttons >> id) & 1; - } - else if (port==0 && device==RETRO_DEVICE_ANALOG) { - if (index==RETRO_DEVICE_INDEX_ANALOG_LEFT) { - if (id==RETRO_DEVICE_ID_ANALOG_X) return pad.laxis.x; - else if (id==RETRO_DEVICE_ID_ANALOG_Y) return pad.laxis.y; - } - else if (index==RETRO_DEVICE_INDEX_ANALOG_RIGHT) { - if (id==RETRO_DEVICE_ID_ANALOG_X) return pad.raxis.x; - else if (id==RETRO_DEVICE_ID_ANALOG_Y) return pad.raxis.y; + } else if (port == 0 && device == RETRO_DEVICE_ANALOG) { + if (index == RETRO_DEVICE_INDEX_ANALOG_LEFT) { + if (id == RETRO_DEVICE_ID_ANALOG_X) + return pad.laxis.x; + else if (id == RETRO_DEVICE_ID_ANALOG_Y) + return pad.laxis.y; + } else if (index == RETRO_DEVICE_INDEX_ANALOG_RIGHT) { + if (id == RETRO_DEVICE_ID_ANALOG_X) + return pad.raxis.x; + else if (id == RETRO_DEVICE_ID_ANALOG_Y) + return pad.raxis.y; } } return 0; } /////////////////////////////// -static void Input_init(const struct retro_input_descriptor *vars) { +static void Input_init(const struct retro_input_descriptor *vars) +{ static int input_initialized = 0; - if (input_initialized) return; + if (input_initialized) + return; LOG_info("Input_init\n"); - + config.controls = core_button_mapping[0].name ? core_button_mapping : default_button_mapping; - + puts("---------------------------------"); - const char* core_button_names[RETRO_BUTTON_COUNT] = {0}; + const char *core_button_names[RETRO_BUTTON_COUNT] = {0}; int present[RETRO_BUTTON_COUNT]; int core_mapped = 0; if (vars) { core_mapped = 1; // identify buttons available in this core - for (int i=0; vars[i].description; i++) { - const struct retro_input_descriptor* var = &vars[i]; - if (var->port!=0 || var->device!=RETRO_DEVICE_JOYPAD || var->index!=0) continue; + for (int i = 0; vars[i].description; i++) { + const struct retro_input_descriptor *var = &vars[i]; + if (var->port != 0 || var->device != RETRO_DEVICE_JOYPAD || var->index != 0) + continue; // TODO: don't ignore unavailable buttons, just override them to BTN_ID_NONE! - if (var->id>=RETRO_BUTTON_COUNT) { - //printf("UNAVAILABLE: %s\n", var->description); fflush(stdout); + if (var->id >= RETRO_BUTTON_COUNT) { + // printf("UNAVAILABLE: %s\n", var->description); fflush(stdout); continue; - } - else { - //printf("PRESENT : %s\n", var->description); fflush(stdout); + } else { + // printf("PRESENT : %s\n", var->description); fflush(stdout); } present[var->id] = 1; core_button_names[var->id] = var->description; } } - + puts("---------------------------------"); - for (int i=0;default_button_mapping[i].name; i++) { - ButtonMapping* mapping = &default_button_mapping[i]; - //LOG_info("DEFAULT %s (%s): <%s>\n", core_button_names[mapping->retro], mapping->name, (mapping->local==BTN_ID_NONE ? "NONE" : device_button_names[mapping->local])); - if (core_button_names[mapping->retro]) mapping->name = (char*)core_button_names[mapping->retro]; + for (int i = 0; default_button_mapping[i].name; i++) { + ButtonMapping *mapping = &default_button_mapping[i]; + // LOG_info("DEFAULT %s (%s): <%s>\n", core_button_names[mapping->retro], mapping->name, + // (mapping->local==BTN_ID_NONE ? "NONE" : device_button_names[mapping->local])); + if (core_button_names[mapping->retro]) + mapping->name = (char *)core_button_names[mapping->retro]; } - + puts("---------------------------------"); - for (int i=0; config.controls[i].name; i++) { - ButtonMapping* mapping = &config.controls[i]; + for (int i = 0; config.controls[i].name; i++) { + ButtonMapping *mapping = &config.controls[i]; mapping->default_ = mapping->local; // ignore mappings that aren't available in this core @@ -3350,22 +3370,25 @@ static void Input_init(const struct retro_input_descriptor *vars) { mapping->ignore = 1; continue; } - //LOG_info("%s: <%s> (%i:%i)\n", mapping->name, (mapping->local==BTN_ID_NONE ? "NONE" : device_button_names[mapping->local]), mapping->local, mapping->retro); + // LOG_info("%s: <%s> (%i:%i)\n", mapping->name, (mapping->local==BTN_ID_NONE ? "NONE" : + // device_button_names[mapping->local]), mapping->local, mapping->retro); } - + puts("---------------------------------"); input_initialized = 1; } -static bool set_rumble_state(unsigned port, enum retro_rumble_effect effect, uint16_t strength) { +static bool set_rumble_state(unsigned port, enum retro_rumble_effect effect, uint16_t strength) +{ // TODO: handle other args? not sure I can VIB_setStrength(strength); return 1; } -static bool environment_callback(unsigned cmd, void *data) { // copied from picoarch initially +static bool environment_callback(unsigned cmd, void *data) +{ // copied from picoarch initially // LOG_info("environment_callback: %i\n", cmd); - - switch(cmd) { + + switch (cmd) { // case RETRO_ENVIRONMENT_SET_ROTATION: { /* 1 */ // LOG_info("RETRO_ENVIRONMENT_SET_ROTATION %i\n", *(int *)data); // core requests frontend to handle rotation // break; @@ -3383,13 +3406,14 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico break; } case RETRO_ENVIRONMENT_SET_MESSAGE: { /* 6 */ - const struct retro_message *message = (const struct retro_message*)data; - if (message) LOG_info("%s\n", message->msg); + const struct retro_message *message = (const struct retro_message *)data; + if (message) + LOG_info("%s\n", message->msg); break; } case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL: { /* 8 */ - // puts("RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL"); - // TODO: used by fceumm at least + // puts("RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL"); + // TODO: used by fceumm at least } case RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY: { /* 9 */ const char **out = (const char **)data; @@ -3401,31 +3425,30 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico case RETRO_ENVIRONMENT_SET_PIXEL_FORMAT: { /* 10 */ const enum retro_pixel_format *format = (const enum retro_pixel_format *)data; LOG_info("Requested pixel format by core: %d\n", *format); // Log the requested format (raw integer value) - + // Check if the requested format is supported if (*format == RETRO_PIXEL_FORMAT_XRGB8888) { fmt = RETRO_PIXEL_FORMAT_XRGB8888; LOG_info("Format supported: RETRO_PIXEL_FORMAT_XRGB8888\n"); - return true; // Indicate success + return true; // Indicate success } else if (*format == RETRO_PIXEL_FORMAT_RGB565) { fmt = RETRO_PIXEL_FORMAT_RGB565; LOG_info("Format supported: RETRO_PIXEL_FORMAT_RGB565\n"); - return true; // Indicate success - } + return true; // Indicate success + } // Log unsupported formats LOG_info("Format not supported, defaulting to RGB565\n"); fmt = RETRO_PIXEL_FORMAT_RGB565; - return false; // Indicate failure + return false; // Indicate failure } case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS: { /* 11 */ // puts("RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS\n"); Input_init((const struct retro_input_descriptor *)data); return false; break; - } + } case RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE: { /* 13 */ - const struct retro_disk_control_callback *var = - (const struct retro_disk_control_callback *)data; + const struct retro_disk_control_callback *var = (const struct retro_disk_control_callback *)data; if (var) { memset(&disk_control_ext, 0, sizeof(struct retro_disk_control_ext_callback)); @@ -3458,7 +3481,7 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico break; } case RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME: { /* 18 */ - bool flag = *(bool*)data; + bool flag = *(bool *)data; // LOG_info("%i: RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME: %i\n", cmd, flag); break; } @@ -3479,10 +3502,10 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico break; } case RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE: { /* 23 */ - struct retro_rumble_interface *iface = (struct retro_rumble_interface*)data; + struct retro_rumble_interface *iface = (struct retro_rumble_interface *)data; - // LOG_info("Setup rumble interface.\n"); - iface->set_rumble_state = set_rumble_state; + // LOG_info("Setup rumble interface.\n"); + iface->set_rumble_state = set_rumble_state; break; } case RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES: { @@ -3494,7 +3517,7 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico case RETRO_ENVIRONMENT_GET_LOG_INTERFACE: { /* 27 */ struct retro_log_callback *log_cb = (struct retro_log_callback *)data; if (log_cb) - log_cb->log = (void (*)(enum retro_log_level, const char*, ...))LOG_note; // same difference + log_cb->log = (void (*)(enum retro_log_level, const char *, ...))LOG_note; // same difference break; } case RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY: { /* 31 */ @@ -3509,9 +3532,9 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico if (infos) { // TODO: store to gamepad_values/gamepad_labels for gamepad_device const struct retro_controller_info *info = &infos[0]; - for (int i=0; inum_types; i++) { + for (int i = 0; i < info->num_types; i++) { const struct retro_controller_description *type = &info->types[i]; - if (exactMatch((char*)type->desc,"dualshock")) { // currently only enabled for PlayStation + if (exactMatch((char *)type->desc, "dualshock")) { // currently only enabled for PlayStation has_custom_controllers = 1; break; } @@ -3525,14 +3548,15 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico // RETRO_ENVIRONMENT_SET_MEMORY_MAPS (36 | RETRO_ENVIRONMENT_EXPERIMENTAL) case RETRO_ENVIRONMENT_GET_LANGUAGE: { /* 39 */ // puts("RETRO_ENVIRONMENT_GET_LANGUAGE"); - if (data) *(int *) data = RETRO_LANGUAGE_ENGLISH; + if (data) + *(int *)data = RETRO_LANGUAGE_ENGLISH; break; } case RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER: { /* (40 | RETRO_ENVIRONMENT_EXPERIMENTAL) */ // puts("RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER"); break; } - + case RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE: { // fixes fbneo save state graphics corruption // puts("RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE"); @@ -3545,7 +3569,7 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico } break; } - + // RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS (42 | RETRO_ENVIRONMENT_EXPERIMENTAL) // RETRO_ENVIRONMENT_GET_VFS_INTERFACE (45 | RETRO_ENVIRONMENT_EXPERIMENTAL) // RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE (47 | RETRO_ENVIRONMENT_EXPERIMENTAL) @@ -3558,7 +3582,8 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico } case RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION: { /* 52 */ // puts("RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION"); - if (data) *(unsigned *)data = 2; + if (data) + *(unsigned *)data = 2; break; } case RETRO_ENVIRONMENT_SET_CORE_OPTIONS: { /* 53 */ @@ -3581,22 +3606,23 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico break; } case RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY: { /* 55 */ - // puts("RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY"); - if (data) { + // puts("RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY"); + if (data) { const struct retro_core_option_display *display = (const struct retro_core_option_display *)data; - LOG_info("Core asked for option key %s to be %s\n", display->key, display->visible ? "visible" : "invisible"); + LOG_info("Core asked for option key %s to be %s\n", display->key, + display->visible ? "visible" : "invisible"); OptionList_setOptionVisibility(&config.core, display->key, display->visible); } break; } case RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION: { /* 57 */ - unsigned *out = (unsigned *)data; - if (out) *out = 1; + unsigned *out = (unsigned *)data; + if (out) + *out = 1; break; } case RETRO_ENVIRONMENT_SET_DISK_CONTROL_EXT_INTERFACE: { /* 58 */ - const struct retro_disk_control_ext_callback *var = - (const struct retro_disk_control_ext_callback *)data; + const struct retro_disk_control_ext_callback *var = (const struct retro_disk_control_ext_callback *)data; if (var) { memcpy(&disk_control_ext, var, sizeof(struct retro_disk_control_ext_callback)); @@ -3635,8 +3661,8 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico // TODO: RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE 64 case RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE: { /* 65 */ - // const struct retro_system_content_info_override* info = (const struct retro_system_content_info_override* )data; - // if (info) LOG_info("has overrides"); + // const struct retro_system_content_info_override* info = (const struct retro_system_content_info_override* + // )data; if (info) LOG_info("has overrides"); break; } // RETRO_ENVIRONMENT_GET_GAME_INFO_EXT 66 @@ -3644,7 +3670,7 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico // puts("RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2"); if (data) { OptionList_reset(); - OptionList_v2_init((const struct retro_core_options_v2 *)data); + OptionList_v2_init((const struct retro_core_options_v2 *)data); } break; } @@ -3657,19 +3683,20 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico } break; } - case RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK: { /* 69 */ + case RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK: { /* 69 */ // puts("RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK"); if (data) { - struct retro_core_options_update_display_callback *update_display_cb = (struct retro_core_options_update_display_callback *) data; + struct retro_core_options_update_display_callback *update_display_cb = + (struct retro_core_options_update_display_callback *)data; core.update_visibility_callback = update_display_cb->callback; - } - else { + } else { core.update_visibility_callback = NULL; } break; } // used by fceumm - // TODO: used by gambatte for L/R palette switching (seems like it needs to return true even if data is NULL to indicate support) + // TODO: used by gambatte for L/R palette switching (seems like it needs to return true even if data is NULL to + // indicate support) case RETRO_ENVIRONMENT_SET_VARIABLE: { // puts("RETRO_ENVIRONMENT_SET_VARIABLE"); const struct retro_variable *var = (const struct retro_variable *)data; @@ -3680,11 +3707,12 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico } int *out = (int *)data; - if (out) *out = 1; - + if (out) + *out = 1; + break; } - + // unused // case RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK: { // puts("RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK"); fflush(stdout); @@ -3698,13 +3726,12 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico // puts("RETRO_ENVIRONMENT_GET_FASTFORWARDING"); fflush(stdout); // break; // }; - case RETRO_ENVIRONMENT_SET_HW_RENDER: - { - struct retro_hw_render_callback *cb = (struct retro_hw_render_callback*)data; - + case RETRO_ENVIRONMENT_SET_HW_RENDER: { + struct retro_hw_render_callback *cb = (struct retro_hw_render_callback *)data; + // Log the requested context - LOG_info("Core requested GL context type: %d, version %d.%d\n", - cb->context_type, cb->version_major, cb->version_minor); + LOG_info("Core requested GL context type: %d, version %d.%d\n", cb->context_type, cb->version_major, + cb->version_minor); // Fallback if version is 0.0 or other unexpected values if (cb->context_type == 4 && cb->version_major == 0 && cb->version_minor == 0) { @@ -3725,12 +3752,14 @@ static bool environment_callback(unsigned cmd, void *data) { // copied from pico /////////////////////////////// -static void hdmimon(void) { +static void hdmimon(void) +{ // handle HDMI change static int had_hdmi = -1; int has_hdmi = GetHDMI(); - if (had_hdmi==-1) had_hdmi = has_hdmi; - if (has_hdmi!=had_hdmi) { + if (had_hdmi == -1) + had_hdmi = has_hdmi; + if (has_hdmi != had_hdmi) { had_hdmi = has_hdmi; LOG_info("restarting after HDMI change...\n"); @@ -3744,7 +3773,7 @@ static void hdmimon(void) { /////////////////////////////// // TODO: this is a dumb API -SDL_Surface* digits; +SDL_Surface *digits; #define DIGIT_WIDTH 9 #define DIGIT_HEIGHT 8 #define DIGIT_TRACKING -2 @@ -3758,385 +3787,376 @@ enum { DIGIT_COUNT, }; #define DIGIT_SPACE DIGIT_COUNT -static void MSG_init(void) { - digits = SDL_CreateRGBSurface(SDL_SWSURFACE,SCALE2(DIGIT_WIDTH*DIGIT_COUNT,DIGIT_HEIGHT),FIXED_DEPTH, 0,0,0,0); +static void MSG_init(void) +{ + digits = + SDL_CreateRGBSurface(SDL_SWSURFACE, SCALE2(DIGIT_WIDTH * DIGIT_COUNT, DIGIT_HEIGHT), FIXED_DEPTH, 0, 0, 0, 0); SDL_FillRect(digits, NULL, RGB_BLACK); - - SDL_Surface* digit; - char* chars[] = { "0","1","2","3","4","5","6","7","8","9","/",".","%","x","(",")", NULL }; - char* c; + + SDL_Surface *digit; + char *chars[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "/", ".", "%", "x", "(", ")", NULL}; + char *c; int i = 0; while ((c = chars[i])) { digit = TTF_RenderUTF8_Blended(font.tiny, c, COLOR_WHITE); - SDL_BlitSurface(digit, NULL, digits, &(SDL_Rect){ (i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w)/2, (SCALE1(DIGIT_HEIGHT) - digit->h)/2}); + SDL_BlitSurface(digit, NULL, digits, + &(SDL_Rect){(i * SCALE1(DIGIT_WIDTH)) + (SCALE1(DIGIT_WIDTH) - digit->w) / 2, + (SCALE1(DIGIT_HEIGHT) - digit->h) / 2}); SDL_FreeSurface(digit); i += 1; } } -static int MSG_blitChar(int n, int x, int y) { - if (n!=DIGIT_SPACE) SDL_BlitSurface(digits, &(SDL_Rect){n*SCALE1(DIGIT_WIDTH),0,SCALE2(DIGIT_WIDTH,DIGIT_HEIGHT)}, screen, &(SDL_Rect){x,y}); +static int MSG_blitChar(int n, int x, int y) +{ + if (n != DIGIT_SPACE) + SDL_BlitSurface(digits, &(SDL_Rect){n * SCALE1(DIGIT_WIDTH), 0, SCALE2(DIGIT_WIDTH, DIGIT_HEIGHT)}, screen, + &(SDL_Rect){x, y}); return x + SCALE1(DIGIT_WIDTH + DIGIT_TRACKING); } -static int MSG_blitInt(int num, int x, int y) { +static int MSG_blitInt(int num, int x, int y) +{ int i = num; int n; - + if (i > 999) { n = i / 1000; i -= n * 1000; - x = MSG_blitChar(n,x,y); + x = MSG_blitChar(n, x, y); } if (i > 99) { n = i / 100; i -= n * 100; - x = MSG_blitChar(n,x,y); - } - else if (num>99) { - x = MSG_blitChar(0,x,y); + x = MSG_blitChar(n, x, y); + } else if (num > 99) { + x = MSG_blitChar(0, x, y); } if (i > 9) { n = i / 10; i -= n * 10; - x = MSG_blitChar(n,x,y); - } - else if (num>9) { - x = MSG_blitChar(0,x,y); + x = MSG_blitChar(n, x, y); + } else if (num > 9) { + x = MSG_blitChar(0, x, y); } - + n = i; - x = MSG_blitChar(n,x,y); - + x = MSG_blitChar(n, x, y); + return x; } -static int MSG_blitDouble(double num, int x, int y) { +static int MSG_blitDouble(double num, int x, int y) +{ int i = num; - int r = (num-i) * 10; + int r = (num - i) * 10; int n; - - x = MSG_blitInt(i, x,y); + + x = MSG_blitInt(i, x, y); n = DIGIT_DOT; - x = MSG_blitChar(n,x,y); - + x = MSG_blitChar(n, x, y); + n = r; - x = MSG_blitChar(n,x,y); + x = MSG_blitChar(n, x, y); return x; } -static void MSG_quit(void) { +static void MSG_quit(void) +{ SDL_FreeSurface(digits); } /////////////////////////////// -static const char* bitmap_font[] = { - ['0'] = - " 111 " - "1 1" - "1 1" - "1 11" - "1 1 1" - "11 1" - "1 1" - "1 1" - " 111 ", - ['1'] = - " 1 " - " 111 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 ", - ['2'] = - " 111 " - "1 1" - " 1" - " 1 " - " 1 " - " 1 " - "1 " - "1 " - "11111", - ['3'] = - " 111 " - "1 1" - " 1" - " 1" - " 111 " - " 1" - " 1" - "1 1" - " 111 ", - ['4'] = - "1 1" - "1 1" - "1 1" - "1 1" - "1 1" - "1 1" - "11111" - " 1" - " 1", - ['5'] = - "11111" - "1 " - "1 " - "1111 " - " 1" - " 1" - " 1" - "1 1" - " 111 ", - ['6'] = - " 111 " - "1 " - "1 " - "1111 " - "1 1" - "1 1" - "1 1" - "1 1" - " 111 ", - ['7'] = - "11111" - " 1" - " 1" - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 ", - ['8'] = - " 111 " - "1 1" - "1 1" - "1 1" - " 111 " - "1 1" - "1 1" - "1 1" - " 111 ", - ['9'] = - " 111 " - "1 1" - "1 1" - "1 1" - "1 1" - " 1111" - " 1" - " 1" - " 111 ", - ['.'] = - " " - " " - " " - " " - " " - " " - " " - " 11 " - " 11 ", - [','] = - " " - " " - " " - " " - " " - " " - " 1 " - " 1 " - " 1 ", - [' '] = - " " - " " - " " - " " - " " - " " - " " - " " - " ", - ['('] = - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 ", - [')'] = - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 ", - ['/'] = - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 " - " 1 ", - ['x'] = - " " - " " - "1 1" - "1 1" - " 1 1 " - " 1 " - " 1 1 " - "1 1" - "1 1", - ['%'] = - " 1 " - "1 1 " - "1 1 1" - " 1 1 " - " 1 " - " 1 1 " - "1 1 1" - " 1 1" - " 1 ", - ['-'] = - " " - " " - " " - " " - " 111 " - " " - " " - " " - " ", - ['c'] = - " " - " " - " 111 " - "1 1" - "1 " - "1 " - "1 " - "1 1" - " 111 ", - ['m'] = - " " - " " - "11 11" - "1 1 1" - "1 1 1" - "1 1" - "1 1" - "1 1" - "1 1", - ['z'] = - " " - " " - " " - "11111" - " 1 " - " 1 " - " 1 " - "1 " - "11111", - ['h'] = - " " - "1 " - "1 " - "1 " - "1111 " - "1 1" - "1 1" - "1 1" - "1 1", +static const char *bitmap_font[] = { + ['0'] = " 111 " + "1 1" + "1 1" + "1 11" + "1 1 1" + "11 1" + "1 1" + "1 1" + " 111 ", + ['1'] = " 1 " + " 111 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 ", + ['2'] = " 111 " + "1 1" + " 1" + " 1 " + " 1 " + " 1 " + "1 " + "1 " + "11111", + ['3'] = " 111 " + "1 1" + " 1" + " 1" + " 111 " + " 1" + " 1" + "1 1" + " 111 ", + ['4'] = "1 1" + "1 1" + "1 1" + "1 1" + "1 1" + "1 1" + "11111" + " 1" + " 1", + ['5'] = "11111" + "1 " + "1 " + "1111 " + " 1" + " 1" + " 1" + "1 1" + " 111 ", + ['6'] = " 111 " + "1 " + "1 " + "1111 " + "1 1" + "1 1" + "1 1" + "1 1" + " 111 ", + ['7'] = "11111" + " 1" + " 1" + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 ", + ['8'] = " 111 " + "1 1" + "1 1" + "1 1" + " 111 " + "1 1" + "1 1" + "1 1" + " 111 ", + ['9'] = " 111 " + "1 1" + "1 1" + "1 1" + "1 1" + " 1111" + " 1" + " 1" + " 111 ", + ['.'] = " " + " " + " " + " " + " " + " " + " " + " 11 " + " 11 ", + [','] = " " + " " + " " + " " + " " + " " + " 1 " + " 1 " + " 1 ", + [' '] = " " + " " + " " + " " + " " + " " + " " + " " + " ", + ['('] = " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 ", + [')'] = " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 ", + ['/'] = " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 " + " 1 ", + ['x'] = " " + " " + "1 1" + "1 1" + " 1 1 " + " 1 " + " 1 1 " + "1 1" + "1 1", + ['%'] = " 1 " + "1 1 " + "1 1 1" + " 1 1 " + " 1 " + " 1 1 " + "1 1 1" + " 1 1" + " 1 ", + ['-'] = " " + " " + " " + " " + " 111 " + " " + " " + " " + " ", + ['c'] = " " + " " + " 111 " + "1 1" + "1 " + "1 " + "1 " + "1 1" + " 111 ", + ['m'] = " " + " " + "11 11" + "1 1 1" + "1 1 1" + "1 1" + "1 1" + "1 1" + "1 1", + ['z'] = " " + " " + " " + "11111" + " 1 " + " 1 " + " 1 " + "1 " + "11111", + ['h'] = " " + "1 " + "1 " + "1 " + "1111 " + "1 1" + "1 1" + "1 1" + "1 1", - }; +}; - void drawRect(int x, int y, int w, int h, uint32_t c, uint32_t *data, int stride) { - for (int _x = x; _x < x + w; _x++) { - data[_x + y * stride] = c; - data[_x + (y + h - 1) * stride] = c; - } - for (int _y = y; _y < y + h; _y++) { - data[x + _y * stride] = c; - data[x + w - 1 + _y * stride] = c; - } +void drawRect(int x, int y, int w, int h, uint32_t c, uint32_t *data, int stride) +{ + for (int _x = x; _x < x + w; _x++) { + data[_x + y * stride] = c; + data[_x + (y + h - 1) * stride] = c; } - - - void fillRect(int x, int y, int w, int h, uint32_t c, uint32_t *data, int stride) { - for (int _y = y; _y < y + h; _y++) { - for (int _x = x; _x < x + w; _x++) { - data[_x + _y * stride] = c; - } + for (int _y = y; _y < y + h; _y++) { + data[x + _y * stride] = c; + data[x + w - 1 + _y * stride] = c; + } +} + + +void fillRect(int x, int y, int w, int h, uint32_t c, uint32_t *data, int stride) +{ + for (int _y = y; _y < y + h; _y++) { + for (int _x = x; _x < x + w; _x++) { + data[_x + _y * stride] = c; } } - - static void blitBitmapText(char* text, int ox, int oy, uint32_t* data, int stride, int width, int height) { - #define CHAR_WIDTH 5 - #define CHAR_HEIGHT 9 - #define LETTERSPACING 1 - - int len = strlen(text); - int w = ((CHAR_WIDTH + LETTERSPACING) * len) - 1; - int h = CHAR_HEIGHT; - - if (ox < 0) ox = width - w + ox; - if (oy < 0) oy = height - h + oy; - - // Clamp to screen bounds (optional but recommended) - if (ox + w > width) w = width - ox; - if (oy + h > height) h = height - oy; - - // Draw background rectangle (black RGBA8888) - fillRect(ox, oy, w, h, 0x000000FF, data, stride); - - data += oy * stride + ox; - - for (int y = 0; y < CHAR_HEIGHT; y++) { - uint32_t* row = data + y * stride; - for (int i = 0; i < len; i++) { - const char* c = bitmap_font[(unsigned char)text[i]]; - for (int x = 0; x < CHAR_WIDTH; x++) { - if (c[y * CHAR_WIDTH + x] == '1') { - *row = 0xFFFFFFFF; // white RGBA8888 - } - row++; +} + +static void blitBitmapText(char *text, int ox, int oy, uint32_t *data, int stride, int width, int height) +{ +#define CHAR_WIDTH 5 +#define CHAR_HEIGHT 9 +#define LETTERSPACING 1 + + int len = strlen(text); + int w = ((CHAR_WIDTH + LETTERSPACING) * len) - 1; + int h = CHAR_HEIGHT; + + if (ox < 0) + ox = width - w + ox; + if (oy < 0) + oy = height - h + oy; + + // Clamp to screen bounds (optional but recommended) + if (ox + w > width) + w = width - ox; + if (oy + h > height) + h = height - oy; + + // Draw background rectangle (black RGBA8888) + fillRect(ox, oy, w, h, 0x000000FF, data, stride); + + data += oy * stride + ox; + + for (int y = 0; y < CHAR_HEIGHT; y++) { + uint32_t *row = data + y * stride; + for (int i = 0; i < len; i++) { + const char *c = bitmap_font[(unsigned char)text[i]]; + for (int x = 0; x < CHAR_WIDTH; x++) { + if (c[y * CHAR_WIDTH + x] == '1') { + *row = 0xFFFFFFFF; // white RGBA8888 } - row += LETTERSPACING; + row++; } + row += LETTERSPACING; } } - - - - +} -void drawGauge(int x, int y, float percent, int width, int height, uint32_t *data, int stride) { +void drawGauge(int x, int y, float percent, int width, int height, uint32_t *data, int stride) +{ // Clamp percent to 0.0 - 1.0 - if (percent < 0.0f) percent = 0.0f; - if (percent > 1.0f) percent = 1.0f; + if (percent < 0.0f) + percent = 0.0f; + if (percent > 1.0f) + percent = 1.0f; - uint8_t red = (uint8_t)(percent * 255.0f); + uint8_t red = (uint8_t)(percent * 255.0f); uint8_t green = (uint8_t)((1.0f - percent) * 255.0f); - uint8_t blue = 0; + uint8_t blue = 0; uint8_t alpha = 255; uint32_t fillColor = (red << 24) | (green << 16) | (blue << 8) | alpha; - uint32_t borderColor = 0xFFFFFFFF; // White RGBA - uint32_t bgColor = 0x000000FF; // Black RGBA + uint32_t borderColor = 0xFFFFFFFF; // White RGBA + uint32_t bgColor = 0x000000FF; // Black RGBA // Background fillRect(x, y, width, height, bgColor, data, stride); @@ -4150,7 +4170,6 @@ void drawGauge(int x, int y, float percent, int width, int height, uint32_t *dat } - /////////////////////////////// static int cpu_ticks = 0; @@ -4162,27 +4181,28 @@ static double use_double = 0; static uint32_t sec_start = 0; #ifdef USES_SWSCALER - static int fit = 1; +static int fit = 1; #else - static int fit = 0; -#endif +static int fit = 0; +#endif -static void selectScaler(int src_w, int src_h, int src_p) { - int src_x,src_y,dst_x,dst_y,dst_w,dst_h,dst_p,scale; +static void selectScaler(int src_w, int src_h, int src_p) +{ + int src_x, src_y, dst_x, dst_y, dst_w, dst_h, dst_p, scale; double aspect; - + int aspect_w = src_w; int aspect_h = CEIL_DIV(aspect_w, core.aspect_ratio); - + // TODO: make sure this doesn't break fit==1 devices - if (aspect_h4) scale = 4; // if (scale>2) scale = 4; // TODO: restore, requires sanity checking - + int scaled_w = src_w * scale; int scaled_h = src_h * scale; - - if (scaling==SCALE_FULLSCREEN) { + + if (scaling == SCALE_FULLSCREEN) { sprintf(scaler_name, "full%i", scale); // type = 'full (oversized)'; dst_w = scaled_w; dst_h = scaled_h; dst_p = dst_w * FIXED_BPP; - } - else if (scaling==SCALE_ASPECT_SCREEN) { - + } else if (scaling == SCALE_ASPECT_SCREEN) { int scale_x = DEVICE_WIDTH / src_w; int scale_y = DEVICE_HEIGHT / src_h; - + // Use the smaller scale to ensure it fits on screen scale = MIN(scale_x, scale_y); aspect = (double)src_w / src_h; - + // Optionally, clamp to a max scale (e.g., 4x) if needed // if (scale > 4) scale = 4; - + int scaled_w = src_w * scale; int scaled_h = src_h * scale; - + // Center the image on screen dst_w = scaled_w; dst_h = scaled_h; dst_x = (DEVICE_WIDTH - dst_w) / 2; dst_y = (DEVICE_HEIGHT - dst_h) / 2; - + dst_p = dst_w * FIXED_BPP; - + sprintf(scaler_name, "raw%i", scale); - LOG_info("ignore core aspect %ix%i\n\n",dst_w,dst_h); - - } - else { + LOG_info("ignore core aspect %ix%i\n\n", dst_w, dst_h); + + } else { double src_aspect_ratio = ((double)src_w) / src_h; // double core_aspect_ratio double fixed_aspect_ratio = ((double)DEVICE_WIDTH) / DEVICE_HEIGHT; int core_aspect = core.aspect_ratio * 1000; int fixed_aspect = fixed_aspect_ratio * 1000; - + // still having trouble with FC's 1.306 (13/10? wtf) on 4:3 devices - // specifically I think it has trouble when src, core, and fixed + // specifically I think it has trouble when src, core, and fixed // ratios don't match - - // it handles src and core matching but fixed not, eg. GB and GBA + + // it handles src and core matching but fixed not, eg. GB and GBA // or core and fixed matching but not src, eg. odd PS resolutions - + // we need to transform the src size to core aspect // then to fixed aspect - - if (core_aspect>fixed_aspect) { + + if (core_aspect > fixed_aspect) { sprintf(scaler_name, "aspect%iL", scale); // letterbox // dst_w = scaled_w; @@ -4365,8 +4381,7 @@ static void selectScaler(int src_w, int src_h, int src_p) { dst_h = scaled_h / aspect_hr; dst_y = (dst_h - scaled_h) / 2; - } - else if (core_aspectw!=dst_w || screen->h!=dst_w || screen->pitch!=dst_p) { - // screen = GFX_resize(dst_w,dst_h,dst_p); + // screen = GFX_resize(dst_w,dst_h,dst_p); // } } static int firstframe = 1; -static void screen_flip(SDL_Surface* screen) { - +static void screen_flip(SDL_Surface *screen) +{ if (use_core_fps) { GFX_flip_fixed_rate(screen, core.fps); - } - else { + } else { GFX_GL_Swap(); // GFX_flip(screen); } @@ -4440,155 +4455,161 @@ static void screen_flip(SDL_Surface* screen) { // couple of animation functions for pixel data keeping them all cause wanna use them later -void applyFadeIn(uint32_t **data, size_t pitch, unsigned width, unsigned height, int *frame_counter, int max_frames) { - size_t pixels_per_row = pitch / sizeof(uint32_t); - static uint32_t temp_buffer[1920 * 1080]; +void applyFadeIn(uint32_t **data, size_t pitch, unsigned width, unsigned height, int *frame_counter, int max_frames) +{ + size_t pixels_per_row = pitch / sizeof(uint32_t); + static uint32_t temp_buffer[1920 * 1080]; - if (*frame_counter >= max_frames) { - return; - } + if (*frame_counter >= max_frames) { + return; + } - float progress = (float)(*frame_counter) / (float)max_frames; - float eased = progress * progress * (3 - 2 * progress); + float progress = (float)(*frame_counter) / (float)max_frames; + float eased = progress * progress * (3 - 2 * progress); - float fade_alpha = eased; + float fade_alpha = eased; - for (unsigned y = 0; y < height; ++y) { - for (unsigned x = 0; x < width; ++x) { - size_t idx = y * pixels_per_row + x; + for (unsigned y = 0; y < height; ++y) { + for (unsigned x = 0; x < width; ++x) { + size_t idx = y * pixels_per_row + x; - uint32_t color = (*data)[idx]; + uint32_t color = (*data)[idx]; - uint8_t a = (color >> 24) & 0xFF; - uint8_t b = (color >> 16) & 0xFF; - uint8_t g = (color >> 8) & 0xFF; - uint8_t r = (color >> 0) & 0xFF; + uint8_t a = (color >> 24) & 0xFF; + uint8_t b = (color >> 16) & 0xFF; + uint8_t g = (color >> 8) & 0xFF; + uint8_t r = (color >> 0) & 0xFF; - r = (uint8_t)(r * fade_alpha); - g = (uint8_t)(g * fade_alpha); - b = (uint8_t)(b * fade_alpha); - a = (uint8_t)(a * fade_alpha); + r = (uint8_t)(r * fade_alpha); + g = (uint8_t)(g * fade_alpha); + b = (uint8_t)(b * fade_alpha); + a = (uint8_t)(a * fade_alpha); - temp_buffer[idx] = (a << 24) | (b << 16) | (g << 8) | r; - } - } + temp_buffer[idx] = (a << 24) | (b << 16) | (g << 8) | r; + } + } - (*frame_counter)++; - *data = temp_buffer; + (*frame_counter)++; + *data = temp_buffer; } -void applyZoomFadeIn(uint32_t **data, size_t pitch, unsigned width, unsigned height, int *frame_counter, int max_frames) { - size_t pixels_per_row = pitch / sizeof(uint32_t); - static uint32_t temp_buffer[1920 * 1080]; +void applyZoomFadeIn(uint32_t **data, size_t pitch, unsigned width, unsigned height, int *frame_counter, int max_frames) +{ + size_t pixels_per_row = pitch / sizeof(uint32_t); + static uint32_t temp_buffer[1920 * 1080]; - if (*frame_counter >= max_frames) - return; + if (*frame_counter >= max_frames) + return; - float progress = (float)(*frame_counter) / (float)max_frames; - float eased = progress * progress * (3.0f - 2.0f * progress); + float progress = (float)(*frame_counter) / (float)max_frames; + float eased = progress * progress * (3.0f - 2.0f * progress); - float start_zoom = 6.0f; - float end_zoom = 1.0f; - float zoom = start_zoom - eased * (start_zoom - end_zoom); + float start_zoom = 6.0f; + float end_zoom = 1.0f; + float zoom = start_zoom - eased * (start_zoom - end_zoom); - float fade_alpha = eased; + float fade_alpha = eased; - int center_x = width / 2; - int center_y = height / 2; + int center_x = width / 2; + int center_y = height / 2; - for (unsigned y = 0; y < height; ++y) { - for (unsigned x = 0; x < width; ++x) { - float src_x = center_x + (x - center_x) / zoom; - float src_y = center_y + (y - center_y) / zoom; + for (unsigned y = 0; y < height; ++y) { + for (unsigned x = 0; x < width; ++x) { + float src_x = center_x + (x - center_x) / zoom; + float src_y = center_y + (y - center_y) / zoom; - int ix = (int)src_x; - int iy = (int)src_y; + int ix = (int)src_x; + int iy = (int)src_y; - size_t dst_idx = y * pixels_per_row + x; - uint32_t color = 0xFF000000; + size_t dst_idx = y * pixels_per_row + x; + uint32_t color = 0xFF000000; - if (ix >= 0 && ix < (int)width && iy >= 0 && iy < (int)height) { - size_t src_idx = iy * pixels_per_row + ix; - color = (*data)[src_idx]; - } + if (ix >= 0 && ix < (int)width && iy >= 0 && iy < (int)height) { + size_t src_idx = iy * pixels_per_row + ix; + color = (*data)[src_idx]; + } - uint8_t a = (color >> 24) & 0xFF; - uint8_t b = (color >> 16) & 0xFF; - uint8_t g = (color >> 8) & 0xFF; - uint8_t r = (color >> 0) & 0xFF; + uint8_t a = (color >> 24) & 0xFF; + uint8_t b = (color >> 16) & 0xFF; + uint8_t g = (color >> 8) & 0xFF; + uint8_t r = (color >> 0) & 0xFF; - r = (uint8_t)(r * fade_alpha); - g = (uint8_t)(g * fade_alpha); - b = (uint8_t)(b * fade_alpha); - a = (uint8_t)(a * fade_alpha); + r = (uint8_t)(r * fade_alpha); + g = (uint8_t)(g * fade_alpha); + b = (uint8_t)(b * fade_alpha); + a = (uint8_t)(a * fade_alpha); - temp_buffer[dst_idx] = (a << 24) | (b << 16) | (g << 8) | r; - } - } + temp_buffer[dst_idx] = (a << 24) | (b << 16) | (g << 8) | r; + } + } - (*frame_counter)++; - *data = temp_buffer; + (*frame_counter)++; + *data = temp_buffer; } // Looney Tunes opening effect :D -void applyCircleReveal(uint32_t **data, size_t pitch, unsigned width, unsigned height, int *frame_counter, int max_frames) { - static uint32_t temp_buffer[1920 * 1080]; +void applyCircleReveal(uint32_t **data, size_t pitch, unsigned width, unsigned height, int *frame_counter, + int max_frames) +{ + static uint32_t temp_buffer[1920 * 1080]; - if (*frame_counter >= max_frames) - return; + if (*frame_counter >= max_frames) + return; - uint32_t *src = *data; - size_t pixels_per_row = pitch / sizeof(uint32_t); + uint32_t *src = *data; + size_t pixels_per_row = pitch / sizeof(uint32_t); - float progress = (float)(*frame_counter) / (float)max_frames; - float eased = progress * progress * (3.0f - 2.0f * progress); + float progress = (float)(*frame_counter) / (float)max_frames; + float eased = progress * progress * (3.0f - 2.0f * progress); - float max_radius = sqrtf((float)(width * width + height * height)) * 0.5f; - float radius = eased * max_radius; + float max_radius = sqrtf((float)(width * width + height * height)) * 0.5f; + float radius = eased * max_radius; - int cx = (int)(width / 2); - int cy = (int)(height / 2); + int cx = (int)(width / 2); + int cy = (int)(height / 2); - for (unsigned y = 0; y < height; ++y) { - for (unsigned x = 0; x < width; ++x) { - size_t idx = y * pixels_per_row + x; + for (unsigned y = 0; y < height; ++y) { + for (unsigned x = 0; x < width; ++x) { + size_t idx = y * pixels_per_row + x; - float dx = (float)x - (float)cx; - float dy = (float)y - (float)cy; - float dist = sqrtf(dx * dx + dy * dy); + float dx = (float)x - (float)cx; + float dy = (float)y - (float)cy; + float dist = sqrtf(dx * dx + dy * dy); - if (dist <= radius) { - temp_buffer[idx] = src[idx]; - } else { - uint32_t color = src[idx]; - uint8_t a = (color >> 24) & 0xFF; - temp_buffer[idx] = (a << 24); - } - } - } + if (dist <= radius) { + temp_buffer[idx] = src[idx]; + } else { + uint32_t color = src[idx]; + uint8_t a = (color >> 24) & 0xFF; + temp_buffer[idx] = (a << 24); + } + } + } - (*frame_counter)++; - *data = temp_buffer; + (*frame_counter)++; + *data = temp_buffer; } -static void video_refresh_callback_main(const void *data, unsigned width, unsigned height, size_t pitch) { +static void video_refresh_callback_main(const void *data, unsigned width, unsigned height, size_t pitch) +{ // return; - + Special_render(); - + // static int tmp_frameskip = 0; // if ((tmp_frameskip++)%2) return; - + static uint32_t last_flip_time = 0; - + // 10 seems to be the sweet spot that allows 2x in NES and SNES and 8x in GB at 60fps // 14 will let GB hit 10x but NES and SNES will drop to 1.5x at 30fps (not sure why) // but 10 hurts PS... // TODO: 10 was based on rg35xx, probably different results on other supported platforms - if (fast_forward && SDL_GetTicks()-last_flip_time<10) return; - - // FFVII menus + if (fast_forward && SDL_GetTicks() - last_flip_time < 10) + return; + + // FFVII menus // 16: 30/200 // 15: 30/180 // 14: 45/180 @@ -4602,62 +4623,67 @@ static void video_refresh_callback_main(const void *data, unsigned width, unsign } fps_ticks += 1; - - if (downsample) pitch /= 2; // everything expects 16 but we're downsampling from 32 - + + if (downsample) + pitch /= 2; // everything expects 16 but we're downsampling from 32 + // if source has changed size (or forced by dst_p==0) // eg. true src + cropped src + fixed dst + cropped dst - if (renderer.dst_p==0 || width!=renderer.true_w || height!=renderer.true_h) { + if (renderer.dst_p == 0 || width != renderer.true_w || height != renderer.true_h) { selectScaler(width, height, pitch); GFX_clearAll(); GFX_resetShaders(); } - + // debug - if (show_debug && !isnan(currentratio) && !isnan(currentfps) && !isnan(currentreqfps) && !isnan(currentbufferms) && - currentbuffersize >= 0 && currentbufferfree >= 0 && SDL_GetTicks() > 5000) { + if (show_debug && !isnan(currentratio) && !isnan(currentfps) && !isnan(currentreqfps) && !isnan(currentbufferms) && + currentbuffersize >= 0 && currentbufferfree >= 0 && SDL_GetTicks() > 5000) { int x = 2 + renderer.src_x; int y = 2 + renderer.src_y; char debug_text[250]; int scale = renderer.scale; - if (scale==-1) scale = 1; // nearest neighbor flag - - sprintf(debug_text, "%ix%i %ix %i/%i", renderer.src_w,renderer.src_h, scale,currentsampleratein,currentsamplerateout); - blitBitmapText(debug_text,x,y,(uint32_t*)data,pitch / 4, width,height); - - sprintf(debug_text, "%.03f/%i/%.0f/%i/%i/%i", currentratio, - currentbuffersize,currentbufferms, currentbufferfree, currentbuffertarget,avgbufferfree); - blitBitmapText(debug_text, x, y + 14, (uint32_t*)data, pitch / 4, width, - height); - - sprintf(debug_text, "%i,%i %ix%i", renderer.dst_x,renderer.dst_y, renderer.src_w*scale,renderer.src_h*scale); - blitBitmapText(debug_text,-x,y,(uint32_t*)data,pitch / 4, width,height); - - sprintf(debug_text, "%ix%i", renderer.dst_w,renderer.dst_h); - blitBitmapText(debug_text,-x,-y,(uint32_t*)data,pitch / 4, width,height); - - //want this to overwrite bottom right in case screen is too small this info more important tbh + if (scale == -1) + scale = 1; // nearest neighbor flag + + sprintf(debug_text, "%ix%i %ix %i/%i", renderer.src_w, renderer.src_h, scale, currentsampleratein, + currentsamplerateout); + blitBitmapText(debug_text, x, y, (uint32_t *)data, pitch / 4, width, height); + + sprintf(debug_text, "%.03f/%i/%.0f/%i/%i/%i", currentratio, currentbuffersize, currentbufferms, + currentbufferfree, currentbuffertarget, avgbufferfree); + blitBitmapText(debug_text, x, y + 14, (uint32_t *)data, pitch / 4, width, height); + + sprintf(debug_text, "%i,%i %ix%i", renderer.dst_x, renderer.dst_y, renderer.src_w * scale, + renderer.src_h * scale); + blitBitmapText(debug_text, -x, y, (uint32_t *)data, pitch / 4, width, height); + + sprintf(debug_text, "%ix%i", renderer.dst_w, renderer.dst_h); + blitBitmapText(debug_text, -x, -y, (uint32_t *)data, pitch / 4, width, height); + + // want this to overwrite bottom right in case screen is too small this info more important tbh PLAT_getCPUTemp(); - sprintf(debug_text, "%.01f/%.01f/%.0f%%/%ihz/%ic", currentfps, currentreqfps,currentcpuse,currentcpuspeed,currentcputemp); - blitBitmapText(debug_text,x,-y,(uint32_t*)data,pitch / 4, width,height); + sprintf(debug_text, "%.01f/%.01f/%.0f%%/%ihz/%ic", currentfps, currentreqfps, currentcpuse, currentcpuspeed, + currentcputemp); + blitBitmapText(debug_text, x, -y, (uint32_t *)data, pitch / 4, width, height); - sprintf(debug_text, "%i/%ix%i/%ix%i/%ix%i", currentshaderpass, currentshadersrcw,currentshadersrch,currentshadertexw,currentshadertexh,currentshaderdstw,currentshaderdsth); - blitBitmapText(debug_text,x,-y - 14,(uint32_t*)data,pitch / 4, width,height); - - double buffer_fill = (double) (currentbuffersize - currentbufferfree) / (double) currentbuffersize; - drawGauge(x, y + 30, buffer_fill, width / 2, 8, (uint32_t*)data, pitch / 4); + sprintf(debug_text, "%i/%ix%i/%ix%i/%ix%i", currentshaderpass, currentshadersrcw, currentshadersrch, + currentshadertexw, currentshadertexh, currentshaderdstw, currentshaderdsth); + blitBitmapText(debug_text, x, -y - 14, (uint32_t *)data, pitch / 4, width, height); + + double buffer_fill = (double)(currentbuffersize - currentbufferfree) / (double)currentbuffersize; + drawGauge(x, y + 30, buffer_fill, width / 2, 8, (uint32_t *)data, pitch / 4); } - + static int frame_counter = 0; - const int max_frames = 8; - if(frame_counter<9) { - applyFadeIn((uint32_t **) &data, pitch, width, height, &frame_counter, max_frames); + const int max_frames = 8; + if (frame_counter < 9) { + applyFadeIn((uint32_t **)&data, pitch, width, height, &frame_counter, max_frames); } // LOG_info("video_refresh_callback: %ix%i@%i %ix%i@%i\n",width,height,pitch,screen->w,screen->h,screen->pitch); - renderer.src = (void*)data; + renderer.src = (void *)data; renderer.dst = screen->pixels; GFX_blitRenderer(&renderer); @@ -4666,27 +4692,29 @@ static void video_refresh_callback_main(const void *data, unsigned width, unsign } -const void* lastframe = NULL; +const void *lastframe = NULL; -static Uint32* rgbaData = NULL; +static Uint32 *rgbaData = NULL; static size_t rgbaDataSize = 0; -static void video_refresh_callback(const void* data, unsigned width, unsigned height, size_t pitch) { - - // I need to check quit here because sometimes quit is true but callback is still called by the core after and it still runs one more frame and it looks ugly :D - if(!quit) { +static void video_refresh_callback(const void *data, unsigned width, unsigned height, size_t pitch) +{ + // I need to check quit here because sometimes quit is true but callback is still called by the core after and it + // still runs one more frame and it looks ugly :D + if (!quit) { if (!rgbaData || rgbaDataSize != width * height) { - if (rgbaData) free(rgbaData); + if (rgbaData) + free(rgbaData); rgbaDataSize = width * height; - rgbaData = (Uint32*)malloc(rgbaDataSize * sizeof(Uint32)); + rgbaData = (Uint32 *)malloc(rgbaDataSize * sizeof(Uint32)); if (!rgbaData) { printf("Failed to allocate memory for RGBA8888 data.\n"); return; } } - if(ambient_mode && !fast_forward && data) - GFX_setAmbientColor(data, width, height,pitch,ambient_mode); + if (ambient_mode && !fast_forward && data) + GFX_setAmbientColor(data, width, height, pitch, ambient_mode); if (!data) { if (lastframe) { @@ -4696,7 +4724,7 @@ static void video_refresh_callback(const void* data, unsigned width, unsigned he } } else if (fmt == RETRO_PIXEL_FORMAT_XRGB8888) { // convert XRGB8888 to RGBA8888 - const uint32_t* src = (const uint32_t*)data; + const uint32_t *src = (const uint32_t *)data; for (unsigned i = 0; i < width * height; ++i) { uint32_t pixel = src[i]; uint8_t r = (pixel >> 16) & 0xFF; @@ -4709,68 +4737,70 @@ static void video_refresh_callback(const void* data, unsigned width, unsigned he } else { // convert RGB565 to RGBA8888 - const uint16_t* srcData = (const uint16_t*)data; - unsigned srcPitchInPixels = pitch / sizeof(uint16_t); + const uint16_t *srcData = (const uint16_t *)data; + unsigned srcPitchInPixels = pitch / sizeof(uint16_t); for (unsigned y = 0; y < height; ++y) { for (unsigned x = 0; x < width; ++x) { uint16_t pixel = srcData[y * srcPitchInPixels + x]; - uint8_t r = ((pixel >> 11) & 0x1F) << 3; - uint8_t g = ((pixel >> 5) & 0x3F) << 2; - uint8_t b = (pixel & 0x1F) << 3; + uint8_t r = ((pixel >> 11) & 0x1F) << 3; + uint8_t g = ((pixel >> 5) & 0x3F) << 2; + uint8_t b = (pixel & 0x1F) << 3; uint8_t a = 0xFF; rgbaData[y * width + x] = (a << 24) | (b << 16) | (g << 8) | r; } } data = rgbaData; - } pitch = width * sizeof(Uint32); lastframe = data; - - video_refresh_callback_main(data,width,height,pitch); + + video_refresh_callback_main(data, width, height, pitch); } } /////////////////////////////// -static void audio_sample_callback(int16_t left, int16_t right) { +static void audio_sample_callback(int16_t left, int16_t right) +{ if (!fast_forward || ff_audio) { if (use_core_fps || fast_forward) { - SND_batchSamples_fixed_rate(&(const SND_Frame){left,right}, 1); - } - else { - SND_batchSamples(&(const SND_Frame){left,right}, 1); + SND_batchSamples_fixed_rate(&(const SND_Frame){left, right}, 1); + } else { + SND_batchSamples(&(const SND_Frame){left, right}, 1); } } } -static size_t audio_sample_batch_callback(const int16_t *data, size_t frames) { +static size_t audio_sample_batch_callback(const int16_t *data, size_t frames) +{ if (!fast_forward || ff_audio) { if (use_core_fps || fast_forward) { - return SND_batchSamples_fixed_rate((const SND_Frame*)data, frames); - } - else { - return SND_batchSamples((const SND_Frame*)data, frames); + return SND_batchSamples_fixed_rate((const SND_Frame *)data, frames); + } else { + return SND_batchSamples((const SND_Frame *)data, frames); } - } - else return frames; + } else + return frames; }; /////////////////////////////////////// -void Core_getName(char* in_name, char* out_name) { +void Core_getName(char *in_name, char *out_name) +{ strcpy(out_name, basename(in_name)); - char* tmp = strrchr(out_name, '_'); + char *tmp = strrchr(out_name, '_'); tmp[0] = '\0'; } -void Core_open(const char* core_path, const char* tag_name) { +void Core_open(const char *core_path, const char *tag_name) +{ LOG_info("Core_open\n"); core.handle = dlopen(core_path, RTLD_LAZY); - - if (!core.handle) LOG_error("%s\n", dlerror()); - + + if (!core.handle) + LOG_error("%s\n", dlerror()); + core.init = dlsym(core.handle, "retro_init"); core.deinit = dlsym(core.handle, "retro_deinit"); core.get_system_info = dlsym(core.handle, "retro_get_system_info"); @@ -4789,43 +4819,44 @@ void Core_open(const char* core_path, const char* tag_name) { core.get_region = dlsym(core.handle, "retro_get_region"); core.get_memory_data = dlsym(core.handle, "retro_get_memory_data"); core.get_memory_size = dlsym(core.handle, "retro_get_memory_size"); - + void (*set_environment_callback)(retro_environment_t); void (*set_video_refresh_callback)(retro_video_refresh_t); void (*set_audio_sample_callback)(retro_audio_sample_t); void (*set_audio_sample_batch_callback)(retro_audio_sample_batch_t); void (*set_input_poll_callback)(retro_input_poll_t); void (*set_input_state_callback)(retro_input_state_t); - + set_environment_callback = dlsym(core.handle, "retro_set_environment"); set_video_refresh_callback = dlsym(core.handle, "retro_set_video_refresh"); set_audio_sample_callback = dlsym(core.handle, "retro_set_audio_sample"); set_audio_sample_batch_callback = dlsym(core.handle, "retro_set_audio_sample_batch"); set_input_poll_callback = dlsym(core.handle, "retro_set_input_poll"); set_input_state_callback = dlsym(core.handle, "retro_set_input_state"); - + struct retro_system_info info = {}; core.get_system_info(&info); - + LOG_info("Block Extract: %d\n", info.block_extract); - Core_getName((char*)core_path, (char*)core.name); - sprintf((char*)core.version, "%s (%s)", info.library_name, info.library_version); - strcpy((char*)core.tag, tag_name); - strcpy((char*)core.extensions, info.valid_extensions); - + Core_getName((char *)core_path, (char *)core.name); + sprintf((char *)core.version, "%s (%s)", info.library_name, info.library_version); + strcpy((char *)core.tag, tag_name); + strcpy((char *)core.extensions, info.valid_extensions); + core.need_fullpath = info.need_fullpath; - - LOG_info("core: %s version: %s tag: %s (valid_extensions: %s need_fullpath: %i)\n", core.name, core.version, core.tag, info.valid_extensions, info.need_fullpath); - - sprintf((char*)core.config_dir, USERDATA_PATH "/%s-%s", core.tag, core.name); - sprintf((char*)core.states_dir, SHARED_USERDATA_PATH "/%s-%s", core.tag, core.name); - sprintf((char*)core.saves_dir, SDCARD_PATH "/Saves/%s", core.tag); - sprintf((char*)core.bios_dir, SDCARD_PATH "/Bios/%s", core.tag); - sprintf((char*)core.cheats_dir, SDCARD_PATH "/Cheats/%s", core.tag); - sprintf((char*)core.overlays_dir, SDCARD_PATH "/Overlays/%s", core.tag); - + + LOG_info("core: %s version: %s tag: %s (valid_extensions: %s need_fullpath: %i)\n", core.name, core.version, + core.tag, info.valid_extensions, info.need_fullpath); + + sprintf((char *)core.config_dir, USERDATA_PATH "/%s-%s", core.tag, core.name); + sprintf((char *)core.states_dir, SHARED_USERDATA_PATH "/%s-%s", core.tag, core.name); + sprintf((char *)core.saves_dir, SDCARD_PATH "/Saves/%s", core.tag); + sprintf((char *)core.bios_dir, SDCARD_PATH "/Bios/%s", core.tag); + sprintf((char *)core.cheats_dir, SDCARD_PATH "/Cheats/%s", core.tag); + sprintf((char *)core.overlays_dir, SDCARD_PATH "/Overlays/%s", core.tag); + char cmd[512]; sprintf(cmd, "mkdir -p \"%s\"; mkdir -p \"%s\"", core.config_dir, core.states_dir); system(cmd); @@ -4837,7 +4868,8 @@ void Core_open(const char* core_path, const char* tag_name) { set_input_poll_callback(input_poll_callback); set_input_state_callback(input_state_callback); } -void Core_init(void) { +void Core_init(void) +{ LOG_info("Core_init\n"); core.init(); core.initialized = 1; @@ -4859,28 +4891,34 @@ void Core_applyCheats(struct Cheats *cheats) } } -int Core_updateAVInfo(void) { +int Core_updateAVInfo(void) +{ struct retro_system_av_info av_info = {}; core.get_system_av_info(&av_info); double a = av_info.geometry.aspect_ratio; - if (a<=0) a = (double)av_info.geometry.base_width / av_info.geometry.base_height; + if (a <= 0) + a = (double)av_info.geometry.base_width / av_info.geometry.base_height; - int changed = (core.fps != av_info.timing.fps || core.sample_rate != av_info.timing.sample_rate || core.aspect_ratio != a); + int changed = + (core.fps != av_info.timing.fps || core.sample_rate != av_info.timing.sample_rate || core.aspect_ratio != a); core.fps = av_info.timing.fps; core.sample_rate = av_info.timing.sample_rate; core.aspect_ratio = a; - if (changed) LOG_info("aspect_ratio: %f (%ix%i) fps: %f\n", a, av_info.geometry.base_width,av_info.geometry.base_height, core.fps); + if (changed) + LOG_info("aspect_ratio: %f (%ix%i) fps: %f\n", a, av_info.geometry.base_width, av_info.geometry.base_height, + core.fps); return changed; } -void Core_load(void) { +void Core_load(void) +{ LOG_info("Core_load\n"); struct retro_game_info game_info; - game_info.path = game.tmp_path[0]?game.tmp_path:game.path; + game_info.path = game.tmp_path[0] ? game.tmp_path : game.path; game_info.data = game.data; game_info.size = game.size; LOG_info("game path: %s (%i)\n", game_info.path, game.size); @@ -4895,16 +4933,19 @@ void Core_load(void) { core.set_controller_port_device(0, RETRO_DEVICE_JOYPAD); // set a default, may update after loading configs Core_updateAVInfo(); } -void Core_reset(void) { +void Core_reset(void) +{ core.reset(); } -void Core_unload(void) { - // Disabling this is a dumb hack for bluetooth, we should really be using +void Core_unload(void) +{ + // Disabling this is a dumb hack for bluetooth, we should really be using // bluealsa with --keep-alive=-1 - but SDL wont reconnect the stream on next start. // Reenable as soon as we have a more recent SDL available, if ever. - //SND_quit(); + // SND_quit(); } -void Core_quit(void) { +void Core_quit(void) +{ if (core.initialized) { SRAM_write(); Cheats_free(); @@ -4914,8 +4955,10 @@ void Core_quit(void) { core.initialized = 0; } } -void Core_close(void) { - if (core.handle) dlclose(core.handle); +void Core_close(void) +{ + if (core.handle) + dlclose(core.handle); } /////////////////////////////////////// @@ -4932,21 +4975,21 @@ enum { }; enum { - STATUS_CONT = 0, - STATUS_SAVE = 1, + STATUS_CONT = 0, + STATUS_SAVE = 1, STATUS_LOAD = 11, STATUS_OPTS = 23, STATUS_DISC = 24, STATUS_QUIT = 30, - STATUS_RESET= 31, + STATUS_RESET = 31, }; // TODO: I don't love how overloaded this has become static struct { - SDL_Surface* bitmap; - SDL_Surface* overlay; - char* items[MENU_ITEM_COUNT]; - char* disc_paths[9]; // up to 9 paths, Arc the Lad Collection is 7 discs + SDL_Surface *bitmap; + SDL_Surface *overlay; + char *items[MENU_ITEM_COUNT]; + char *disc_paths[9]; // up to 9 paths, Arc the Lad Collection is 7 discs char minui_dir[256]; char slot_path[256]; char base_path[256]; @@ -4957,28 +5000,28 @@ static struct { int slot; int save_exists; int preview_exists; -} menu = { - .bitmap = NULL, - .disc = -1, - .total_discs = 0, - .save_exists = 0, - .preview_exists = 0, - - .items = { - [ITEM_CONT] = "Continue", - [ITEM_SAVE] = "Save", - [ITEM_LOAD] = "Load", - [ITEM_OPTS] = "Options", - [ITEM_QUIT] = "Quit", - } -}; - -void Menu_init(void) { - menu.overlay = SDL_CreateRGBSurfaceWithFormat(SDL_SWSURFACE,DEVICE_WIDTH,DEVICE_HEIGHT,32,SDL_PIXELFORMAT_RGBA8888); +} menu = {.bitmap = NULL, + .disc = -1, + .total_discs = 0, + .save_exists = 0, + .preview_exists = 0, + + .items = { + [ITEM_CONT] = "Continue", + [ITEM_SAVE] = "Save", + [ITEM_LOAD] = "Load", + [ITEM_OPTS] = "Options", + [ITEM_QUIT] = "Quit", + }}; + +void Menu_init(void) +{ + menu.overlay = + SDL_CreateRGBSurfaceWithFormat(SDL_SWSURFACE, DEVICE_WIDTH, DEVICE_HEIGHT, 32, SDL_PIXELFORMAT_RGBA8888); SDL_SetSurfaceBlendMode(menu.overlay, SDL_BLENDMODE_BLEND); Uint32 color = SDL_MapRGBA(menu.overlay->format, 0, 0, 0, 0); SDL_FillRect(screen, NULL, color); - + char emu_name[256]; getEmuName(game.path, emu_name); sprintf(menu.minui_dir, SHARED_USERDATA_PATH "/.minui/%s", emu_name); @@ -4986,29 +5029,31 @@ void Menu_init(void) { // always sanitized/outer name, to keep main UI from having to inspect archives sprintf(menu.slot_path, "%s/%s.txt", menu.minui_dir, game.name); - - if (simple_mode) menu.items[ITEM_OPTS] = "Reset"; - + + if (simple_mode) + menu.items[ITEM_OPTS] = "Reset"; + if (game.m3u_path[0]) { - char* tmp; + char *tmp; strcpy(menu.base_path, game.m3u_path); tmp = strrchr(menu.base_path, '/') + 1; tmp[0] = '\0'; - - //read m3u file - FILE* file = fopen(game.m3u_path, "r"); + + // read m3u file + FILE *file = fopen(game.m3u_path, "r"); if (file) { char line[256]; - while (fgets(line,256,file)!=NULL) { + while (fgets(line, 256, file) != NULL) { normalizeNewline(line); trimTrailingNewlines(line); - if (strlen(line)==0) continue; // skip empty lines - + if (strlen(line) == 0) + continue; // skip empty lines + char disc_path[256]; strcpy(disc_path, menu.base_path); tmp = disc_path + strlen(disc_path); strcpy(tmp, line); - + // found a valid disc path if (exists(disc_path)) { menu.disc_paths[menu.total_discs] = strdup(disc_path); @@ -5023,18 +5068,21 @@ void Menu_init(void) { } } } -void Menu_quit(void) { +void Menu_quit(void) +{ SDL_FreeSurface(menu.overlay); } -void Menu_beforeSleep() { +void Menu_beforeSleep() +{ SRAM_write(); RTC_write(); State_autosave(); putFile(AUTO_RESUME_PATH, game.path + strlen(SDCARD_PATH)); - + PWR_setCPUSpeed(CPU_SPEED_MENU); } -void Menu_afterSleep() { +void Menu_afterSleep() +{ unlink(AUTO_RESUME_PATH); setOverclock(overclock); } @@ -5046,74 +5094,82 @@ enum { MENU_CALLBACK_EXIT, MENU_CALLBACK_NEXT_ITEM, }; -typedef int (*MenuList_callback_t)(MenuList* list, int i); +typedef int (*MenuList_callback_t)(MenuList *list, int i); typedef struct MenuItem { - char* name; - char* desc; - char** values; - char* key; // optional, used by options - int id; // optional, used by bindings + char *name; + char *desc; + char **values; + char *key; // optional, used by options + int id; // optional, used by bindings int value; - MenuList* submenu; + MenuList *submenu; MenuList_callback_t on_confirm; MenuList_callback_t on_change; } MenuItem; enum { - MENU_LIST, // eg. save and main menu - MENU_VAR, // eg. frontend + MENU_LIST, // eg. save and main menu + MENU_VAR, // eg. frontend MENU_FIXED, // eg. emulator MENU_INPUT, // eg. renders like but MENU_VAR but handles input differently }; typedef struct MenuList { int type; int max_width; // cached on first draw - char* desc; - char* category; // currently displayed category - MenuItem* items; + char *desc; + char *category; // currently displayed category + MenuItem *items; MenuList_callback_t on_confirm; MenuList_callback_t on_change; } MenuList; -static int Menu_messageWithFont(char* message, char** pairs, TTF_Font* f) { +static int Menu_messageWithFont(char *message, char **pairs, TTF_Font *f) +{ GFX_setMode(MODE_MAIN); int dirty = 1; while (1) { GFX_startFrame(); PAD_poll(); - if (PAD_justPressed(BTN_A) || PAD_justPressed(BTN_B)) break; - + if (PAD_justPressed(BTN_A) || PAD_justPressed(BTN_B)) + break; + PWR_update(&dirty, NULL, Menu_beforeSleep, Menu_afterSleep); - - + + GFX_clear(screen); - GFX_blitMessage(f, message, screen, &(SDL_Rect){SCALE1(PADDING),SCALE1(PADDING),screen->w-SCALE1(2*PADDING),screen->h-SCALE1(PILL_SIZE+PADDING)}); + GFX_blitMessage(f, message, screen, + &(SDL_Rect){SCALE1(PADDING), SCALE1(PADDING), screen->w - SCALE1(2 * PADDING), + screen->h - SCALE1(PILL_SIZE + PADDING)}); GFX_blitButtonGroup(pairs, 0, screen, 1); GFX_flip(screen); dirty = 0; - - + + hdmimon(); } GFX_setMode(MODE_MENU); return MENU_CALLBACK_NOP; // TODO: this should probably be an arg } -static int Menu_message(char* message, char** pairs) { +static int Menu_message(char *message, char **pairs) +{ return Menu_messageWithFont(message, pairs, font.medium); } -static int Menu_options(MenuList* list); +static int Menu_options(MenuList *list); -static int MenuList_freeItems(MenuList* list, int i) { +static int MenuList_freeItems(MenuList *list, int i) +{ // TODO: what calls this? do menu's register for needing it? then call it on quit for each? - if (list->items) free(list->items); + if (list->items) + free(list->items); return MENU_CALLBACK_NOP; } -static int OptionFrontend_optionChanged(MenuList* list, int i) { - MenuItem* item = &list->items[i]; +static int OptionFrontend_optionChanged(MenuList *list, int i) +{ + MenuItem *item = &list->items[i]; Config_syncFrontend(item->key, item->value); return MENU_CALLBACK_NOP; } @@ -5122,40 +5178,42 @@ static MenuList OptionFrontend_menu = { .on_change = OptionFrontend_optionChanged, .items = NULL, }; -static int OptionFrontend_openMenu(MenuList* list, int i) { - if (OptionFrontend_menu.items==NULL) { +static int OptionFrontend_openMenu(MenuList *list, int i) +{ + if (OptionFrontend_menu.items == NULL) { // TODO: where do I free this? I guess I don't :sweat_smile: if (!config.frontend.enabled_count) { int enabled_count = 0; - for (int i=0; ilock) continue; + for (int i = 0; i < config.frontend.count; i++) { + Option *item = &config.frontend.options[i]; + if (item->lock) + continue; config.frontend.enabled_options[j] = item; j += 1; } } - OptionFrontend_menu.items = calloc(config.frontend.enabled_count+1, sizeof(MenuItem)); - for (int j=0; jkey = option->key; item->name = option->name; item->desc = option->desc; item->value = option->value; item->values = option->labels; } - } - else { + } else { // update values - for (int j=0; jvalue = option->value; } } @@ -5163,19 +5221,18 @@ static int OptionFrontend_openMenu(MenuList* list, int i) { return MENU_CALLBACK_NOP; } -static int OptionEmulator_optionChanged(MenuList* list, int i) { - MenuItem* item = &list->items[i]; - Option* option = OptionList_getOption(&config.core, item->key); - LOG_info("%s (%s) changed from `%s` (%s) to `%s` (%s)\n", item->name, item->key, - item->values[option->value], option->values[option->value], - item->values[item->value], option->values[item->value] - ); +static int OptionEmulator_optionChanged(MenuList *list, int i) +{ + MenuItem *item = &list->items[i]; + Option *option = OptionList_getOption(&config.core, item->key); + LOG_info("%s (%s) changed from `%s` (%s) to `%s` (%s)\n", item->name, item->key, item->values[option->value], + option->values[option->value], item->values[item->value], option->values[item->value]); OptionList_setOptionRawValue(&config.core, item->key, item->value); return MENU_CALLBACK_NOP; } -static int OptionEmulator_openMenu(MenuList* list, int i); -static int OptionEmulator_optionDetail(MenuList* list, int i); +static int OptionEmulator_openMenu(MenuList *list, int i); +static int OptionEmulator_optionDetail(MenuList *list, int i); static MenuList OptionEmulator_menu = { .type = MENU_FIXED, @@ -5184,8 +5241,9 @@ static MenuList OptionEmulator_menu = { .items = NULL, }; -static int OptionEmulator_optionDetail(MenuList* list, int i) { - MenuItem* item = &list->items[i]; +static int OptionEmulator_optionDetail(MenuList *list, int i) +{ + MenuItem *item = &list->items[i]; if (item->values == NULL) { // This is a category item @@ -5200,20 +5258,22 @@ static int OptionEmulator_optionDetail(MenuList* list, int i) { OptionEmulator_openMenu(list, 0); list->category = NULL; - config.core.enabled_count = prev_enabled_count ; - config.core.enabled_options = prev_enabled ; + config.core.enabled_count = prev_enabled_count; + config.core.enabled_options = prev_enabled; OptionEmulator_menu.items = prev_items; LOG_info("%s: back to root menu\n", __FUNCTION__); - } - else { - Option* option = OptionList_getOption(&config.core, item->key); - if (option->full) return Menu_messageWithFont(option->full, (char*[]){ "B","BACK", NULL }, font.medium); - else return MENU_CALLBACK_NOP; + } else { + Option *option = OptionList_getOption(&config.core, item->key); + if (option->full) + return Menu_messageWithFont(option->full, (char *[]){"B", "BACK", NULL}, font.medium); + else + return MENU_CALLBACK_NOP; } } -static int OptionEmulator_openMenu(MenuList* list, int index) { +static int OptionEmulator_openMenu(MenuList *list, int index) +{ LOG_info("%s: limit to category %s\n", __FUNCTION__, list->category ? list->category : ""); if (list->category == NULL) { @@ -5224,8 +5284,8 @@ static int OptionEmulator_openMenu(MenuList* list, int index) { } int enabled_count = 0; - config.core.enabled_options = calloc(config.core.count + 1, sizeof(Option*)); - for (int i=0; i