Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 52 additions & 14 deletions runtime/gamelib.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,7 @@ static int candidates(const char *game_dir, char out[3][1100]) {
return n;
}

bool gamelib_present(const char *game_dir) {
if (g_tables) return true;
char c[3][1100];
int n = candidates(game_dir, c);
for (int i = 0; i < n; i++)
if (exists(c[i]) && id_matches(c[i])) return true;
return false;
}

static const GameLibTables *open_lib(const char *path) {
static const GameLibTables *open_lib(const char *path, bool allow_id_mismatch) {
#ifdef _WIN32
HMODULE h = LoadLibraryA(path);
if (!h) { snprintf(g_error, sizeof g_error, "can't load %s (error %lu)", path, GetLastError()); return NULL; }
Expand All @@ -175,13 +166,56 @@ static const GameLibTables *open_lib(const char *path) {
#endif
if (!entry) { snprintf(g_error, sizeof g_error, "%s: not game code", path); return NULL; }
const GameLibTables *t = entry();
if (!t || t->abi != GAMELIB_ABI || !t->id || strcmp(t->id, gamelib_id())) {
if (!t || t->abi != GAMELIB_ABI) {
snprintf(g_error, sizeof g_error, "%s was built for another version", path);
return NULL; // (left loaded: nothing of it runs)
}
if (!t->id || strcmp(t->id, gamelib_id())) {
if (!allow_id_mismatch) {
snprintf(g_error, sizeof g_error, "%s was built for another version", path);
return NULL;
}
LOG("[gamelib] note: using game code built for version ID %s (current runtime expects %s)\n",
t->id ? t->id : "?", gamelib_id());
}
return t;
}

bool gamelib_abi_compatible(const char *game_dir) {
char c[3][1100];
int n = candidates(game_dir, c);
for (int i = 0; i < n; i++) {
if (!exists(c[i])) continue;
const GameLibTables *t = open_lib(c[i], true);
if (t && take_sites(t)) return true;
}
return false;
}

bool gamelib_exact_id(const char *game_dir) {
char c[3][1100];
int n = candidates(game_dir, c);
for (int i = 0; i < n; i++) {
if (exists(c[i]) && id_matches(c[i])) return true;
}
return false;
}

bool gamelib_present(const char *game_dir) {
if (g_tables) return true;
char c[3][1100];
int n = candidates(game_dir, c);
const char *e = getenv("SAVAGEWIND_REUSE_GAMELIB");
bool disallow_reuse = e && strcmp(e, "0") == 0;
for (int i = 0; i < n; i++) {
if (exists(c[i])) {
if (id_matches(c[i])) return true;
if (!disallow_reuse && gamelib_abi_compatible(game_dir)) return true;
}
}
return false;
}

bool gamelib_load(const char *game_dir, char *why, size_t why_size) {
static bool tried;
if (!tried) {
Expand All @@ -190,17 +224,21 @@ bool gamelib_load(const char *game_dir, char *why, size_t why_size) {
char c[3][1100];
int n = candidates(game_dir, c);
const char *env = getenv("SAVAGEWIND_GAME_LIB");
const char *reuse_env = getenv("SAVAGEWIND_REUSE_GAMELIB");
bool allow_reuse = !reuse_env || strcmp(reuse_env, "0") != 0;
for (int i = 0; i < n && !g_tables; i++) {
if (!exists(c[i])) continue;
bool given = i == 0 && env && *env; // SAVAGEWIND_GAME_LIB: loaded as given, the library's own id decides
if (!given && !id_matches(c[i])) {
bool matches = id_matches(c[i]);
if (!given && !matches && !allow_reuse) {
snprintf(g_error, sizeof g_error, "%s was built for another version", c[i]);
continue;
}
g_tables = open_lib(c[i]);
g_tables = open_lib(c[i], given || allow_reuse);
if (g_tables && !take_sites(g_tables)) g_tables = NULL;
if (g_tables) {
LOG("[gamelib] %s (game version %s, %u sites)\n", c[i], g_game_version, *g_tables->nsites);
LOG("[gamelib] %s (game version %s, %u sites)%s\n", c[i], g_game_version, *g_tables->nsites,
matches ? "" : " [reused from previous build]");
#ifdef GAMELIB_ID_COMPAT
LOG("[gamelib] target: %s\n", gamelib_compat() ? "compatible (" GAMELIB_ARCH_COMPAT
", no FMA instructions: slower)"
Expand Down
4 changes: 4 additions & 0 deletions runtime/gamelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ const GameLibTables *gamelib_tables(void);
void gamelib_sync(void);
// True when a library usable with this build is in one of those places (without loading it).
bool gamelib_present(const char *game_dir);
// True when the library matches the exact build ID of the current runtime.
bool gamelib_exact_id(const char *game_dir);

// The game code's target on this CPU (#9). x86-64 builds the game code for x86-64-v3 (AVX2, FMA, BMI2: the Makefile's
// GENARCH) where the CPU has those, else for the compatible target (GENARCH_COMPAT: x86-64-v2, no FMA instructions -
Expand All @@ -84,6 +86,8 @@ const char *gamelib_id(void); // the id a library for this CPU has (GAMELIB_ID
const char *gamelib_cpu_problem(void);
// True when game_dir holds a library built for the other target (a game folder moved from a PC of the other kind)
bool gamelib_other_cpu(const char *game_dir);
// True when game_dir holds an existing game library with matching ABI (reusable without full recompilation).
bool gamelib_abi_compatible(const char *game_dir);

#ifdef __cplusplus
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "kernel.h"
#include "control.h"
#include "launch_flags_boot.h"
#include "updater.h"

const char *g_romfs_dir;
uint64_t g_program_id;
Expand Down Expand Up @@ -348,6 +349,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "[savagewind] Savage Wind %s (%s)\n", rt_version(), SW_SOURCE);
launch_flags_boot(argc, argv); // the saved launch options (runtime/launch_flags.h): in the environment before anything reads it
control_init();
updater_init();
const char *root = "extracted"; // (in the data root)
bool skip_launcher = getenv("SAVAGEWIND_NO_LAUNCHER") || getenv("SAVAGEWIND_INPUT"); // tests boot straight in
bool config = false;
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/de.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "Suche Spieldateien...")
T("Copying the game files...", "Kopiere Spieldateien...")
T("Game files ready.", "Spieldateien bereit.")
T("Game files ready (previous game build).", "Spieldateien bereit (vorherige Spielversion).")
T("Rebuild in Game Files anytime to update to latest patches.", "Jederzeit unter Spieldateien neu erstellen, um neueste Patches zu erhalten.")
T("Update available: %s", "Update verfügbar: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "%d Schriftdatei(en) importiert, %d nicht erkannt. Aktiv ab dem nächsten Spielstart.")
T("%d font file(s) imported. Used from the next game start.", "%d Schriftdatei(en) importiert. Aktiv ab dem nächsten Spielstart.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/es.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "Buscando los archivos del juego...")
T("Copying the game files...", "Copiando los archivos del juego...")
T("Game files ready.", "Archivos del juego listos.")
T("Game files ready (previous game build).", "Archivos del juego listos (compilación previa).")
T("Rebuild in Game Files anytime to update to latest patches.", "Reconstruye en Archivos del juego en cualquier momento para aplicar los últimos parches.")
T("Update available: %s", "Actualización disponible: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "%d archivo(s) de fuente importado(s), %d no reconocido(s). Se usan desde el próximo inicio del juego.")
T("%d font file(s) imported. Used from the next game start.", "%d archivo(s) de fuente importado(s). Se usan desde el próximo inicio del juego.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/fr.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "Recherche des fichiers du jeu...")
T("Copying the game files...", "Copie des fichiers du jeu...")
T("Game files ready.", "Fichiers du jeu prêts.")
T("Game files ready (previous game build).", "Fichiers du jeu prêts (version précédente).")
T("Rebuild in Game Files anytime to update to latest patches.", "Reconstruisez dans Fichiers du jeu à tout moment pour appliquer les derniers correctifs.")
T("Update available: %s", "Mise à jour disponible : %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "%d fichier(s) de police importé(s), %d non reconnu(s). Utilisés dès le prochain lancement du jeu.")
T("%d font file(s) imported. Used from the next game start.", "%d fichier(s) de police importé(s). Utilisés dès le prochain lancement du jeu.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/he.inc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ T("Checking the game files...", "בודק את קובצי המשחק...")
T("Copying the game files...", "מעתיק את קובצי המשחק...")
T("Downloadable content ready.", "התוכן להורדה מוכן.")
T("Game files ready.", "קובצי המשחק מוכנים.")
T("Game files ready (previous game build).", "קובצי המשחק מוכנים (בנייה קודמת).")
T("Rebuild in Game Files anytime to update to latest patches.", "בנה מחדש בקובצי משחק בכל עת כדי להחיל את הטלאים האחרונים.")
T("Update available: %s", "עדכון זמין: %s")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "קובצי גופן שיובאו: %d, שלא זוהו: %d. בשימוש החל מההפעלה הבאה של המשחק.")
T("%d font file(s) imported. Used from the next game start.", "קובצי גופן שיובאו: %d. בשימוש החל מההפעלה הבאה של המשחק.")
T("Imported fonts removed: the substitute font is used.", "הגופנים המיובאים הוסרו: משתמשים בגופן החלופי.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/it.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "Ricerca dei file di gioco...")
T("Copying the game files...", "Copia dei file di gioco...")
T("Game files ready.", "File di gioco pronti.")
T("Game files ready (previous game build).", "File di gioco pronti (versione precedente).")
T("Rebuild in Game Files anytime to update to latest patches.", "Ricostruisci in File di gioco in qualsiasi momento per applicare le ultime patch.")
T("Update available: %s", "Aggiornamento disponibile: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "%d file di font importati, %d non riconosciuti. In uso dal prossimo avvio del gioco.")
T("%d font file(s) imported. Used from the next game start.", "%d file di font importati. In uso dal prossimo avvio del gioco.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/ja.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "ゲームファイルを探しています...")
T("Copying the game files...", "ゲームファイルをコピーしています...")
T("Game files ready.", "ゲームファイルの準備ができました。")
T("Game files ready (previous game build).", "ゲームファイルの準備ができました(以前のビルド)。")
T("Rebuild in Game Files anytime to update to latest patches.", "最新パッチを適用するには、いつでも「ゲームファイル」で再ビルドできます。")
T("Update available: %s", "アップデートが利用可能: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "%d個のフォントファイルをインポートしました(%d個は認識できませんでした)。次回のゲーム起動から使われます。")
T("%d font file(s) imported. Used from the next game start.", "%d個のフォントファイルをインポートしました。次回のゲーム起動から使われます。")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/ko.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "게임 파일을 찾는 중...")
T("Copying the game files...", "게임 파일을 복사하는 중...")
T("Game files ready.", "게임 파일이 준비되었습니다.")
T("Game files ready (previous game build).", "게임 파일이 준비되었습니다 (이전 빌드).")
T("Rebuild in Game Files anytime to update to latest patches.", "최신 패치를 적용하려면 언제든지 게임 파일에서 다시 빌드할 수 있습니다.")
T("Update available: %s", "업데이트 사용 가능: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "글꼴 파일 %d개를 가져왔고 %d개는 인식하지 못했습니다. 다음 게임 시작부터 사용됩니다.")
T("%d font file(s) imported. Used from the next game start.", "글꼴 파일 %d개를 가져왔습니다. 다음 게임 시작부터 사용됩니다.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/nl.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "Spelbestanden zoeken...")
T("Copying the game files...", "Spelbestanden kopiëren...")
T("Game files ready.", "Spelbestanden klaar.")
T("Game files ready (previous game build).", "Spelbestanden klaar (vorige build).")
T("Rebuild in Game Files anytime to update to latest patches.", "Herbouw op elk moment in Spelbestanden om de nieuwste patches toe te passen.")
T("Update available: %s", "Update beschikbaar: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "%d lettertypebestand(en) geïmporteerd, %d niet herkend. Gebruikt vanaf de volgende spelstart.")
T("%d font file(s) imported. Used from the next game start.", "%d lettertypebestand(en) geïmporteerd. Gebruikt vanaf de volgende spelstart.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/pt.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "Procurando os arquivos do jogo...")
T("Copying the game files...", "Copiando os arquivos do jogo...")
T("Game files ready.", "Arquivos do jogo prontos.")
T("Game files ready (previous game build).", "Arquivos do jogo prontos (versão anterior).")
T("Rebuild in Game Files anytime to update to latest patches.", "Reconstrua em Arquivos do jogo a qualquer momento para aplicar as atualizações mais recentes.")
T("Update available: %s", "Atualização disponível: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "%d arquivo(s) de fonte importado(s), %d não reconhecido(s). Usados a partir da próxima vez que o jogo iniciar.")
T("%d font file(s) imported. Used from the next game start.", "%d arquivo(s) de fonte importado(s). Usados a partir da próxima vez que o jogo iniciar.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/ru.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "Поиск файлов игры...")
T("Copying the game files...", "Копирование файлов игры...")
T("Game files ready.", "Файлы игры готовы.")
T("Game files ready (previous game build).", "Файлы игры готовы (предыдущая сборка).")
T("Rebuild in Game Files anytime to update to latest patches.", "Пересоберите в Файлы игры в любое время для применения последних патчей.")
T("Update available: %s", "Доступно обновление: %s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "Импортировано файлов шрифтов: %d, не распознано: %d. Используются со следующего запуска игры.")
T("%d font file(s) imported. Used from the next game start.", "Импортировано файлов шрифтов: %d. Используются со следующего запуска игры.")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/th.inc
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ T("Looking for the game files...", "กำลังค้นหาไฟล์
T("Checking the game files...", "กำลังตรวจสอบไฟล์เกม...")
T("Copying the game files...", "กำลังคัดลอกไฟล์เกม...")
T("Game files ready.", "ไฟล์เกมพร้อมแล้ว")
T("Game files ready (previous game build).", "ไฟล์เกมพร้อมแล้ว (บิลด์ก่อนหน้า)")
T("Rebuild in Game Files anytime to update to latest patches.", "สร้างใหม่ในไฟล์เกมได้ทุกเมื่อเพื่ออัปเดตแพตช์ล่าสุด")
T("Update available: %s", "มีอัปเดตใหม่: %s")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "นำเข้าไฟล์ฟอนต์ %d ไฟล์ ไม่รู้จัก %d ไฟล์ ใช้ตั้งแต่การเริ่มเกมครั้งถัดไป")
T("%d font file(s) imported. Used from the next game start.", "นำเข้าไฟล์ฟอนต์ %d ไฟล์ ใช้ตั้งแต่การเริ่มเกมครั้งถัดไป")
T("Imported fonts removed: the substitute font is used.", "ลบฟอนต์ที่นำเข้าแล้ว: ใช้ฟอนต์ทดแทน")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/zh-Hans.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "正在查找游戏文件...")
T("Copying the game files...", "正在复制游戏文件...")
T("Game files ready.", "游戏文件已就绪。")
T("Game files ready (previous game build).", "游戏文件已就绪(旧版本生成)。")
T("Rebuild in Game Files anytime to update to latest patches.", "可随时在游戏文件中重新生成以应用最新补丁。")
T("Update available: %s", "有可用更新:%s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "已导入%d个字体文件,%d个无法识别。下次启动游戏时生效。")
T("%d font file(s) imported. Used from the next game start.", "已导入%d个字体文件。下次启动游戏时生效。")
Expand Down
3 changes: 3 additions & 0 deletions runtime/ui/i18n/zh-Hant.inc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ T("Make sure there's enough free space and try again. The log has the details.",
T("Looking for the game files...", "正在尋找遊戲檔案...")
T("Copying the game files...", "正在複製遊戲檔案...")
T("Game files ready.", "遊戲檔案已就緒。")
T("Game files ready (previous game build).", "遊戲檔案已就緒(舊版本建置)。")
T("Rebuild in Game Files anytime to update to latest patches.", "可隨時在遊戲檔案中重新建置以套用最新修正。")
T("Update available: %s", "有可用更新:%s")
T("NSO", "")
T("%d font file(s) imported, %d not recognized. Used from the next game start.", "已匯入%d個字型檔案,%d個無法辨識。下次啟動遊戲時生效。")
T("%d font file(s) imported. Used from the next game start.", "已匯入%d個字型檔案。下次啟動遊戲時生效。")
Expand Down
Loading
Loading