Skip to content

Commit

Permalink
v0.2.0 (#62)
Browse files Browse the repository at this point in the history
* Refactored menu, added font generator and fixed HD texture errors

* Uploaded translations

* Added a warning about mods

* Added update system

* Changed en message a little bit

* Updated commit-hash

* Added try/catch to avoid messing retro if github or the device doesnt have internet

* Git now read directly and changed game icons

* Reworked git generation to live on build time

* Switched back to sync

* Add comment to explain why we avoid roy textures

* Fixed git error, converted script to ps1 and added log file

* Removed comments
  • Loading branch information
KiritoDv authored Jun 4, 2024
1 parent 5926505 commit ac95511
Show file tree
Hide file tree
Showing 36 changed files with 1,014 additions and 423 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
cache: true
cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' # optional, change this to force refresh cache
cache-path: '${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:' # optional, change this to specify the cache path
- run: chmod +x ./build.sh
- run: ./build.sh
- run: flutter config --enable-macos-desktop
- run: flutter build -v macos --release
- run: ditto -c -k --sequesterRsrc --keepParent retro.app $GITHUB_WORKSPACE/retro.zip
Expand All @@ -36,6 +38,7 @@ jobs:
cache: true
cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' # optional, change this to force refresh cache
cache-path: '${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:' # optional, change this to specify the cache path
- run: ./build.ps1
- run: flutter config --enable-windows-desktop
- run: flutter build windows --release
- uses: actions/upload-artifact@v3
Expand All @@ -54,13 +57,15 @@ jobs:
cache: true
cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:' # optional, change this to force refresh cache
cache-path: '${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:' # optional, change this to specify the cache path
- run: chmod +x ./build.sh
- run: ./build.sh
- run: flutter config --enable-linux-desktop
- run: flutter build linux --release
- name: Create AppImage
run: |
wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod a+x appimagetool-x86_64.AppImage
# Create AppDir
cp -r build/linux/x64/release/bundle/ retro.AppDir
cp assets/icon-macos.png retro.AppDir/retro.png
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ app.*.symbols
# Obfuscation related
app.*.map.json

# Autogenerated file
# lib/auto/build.dart

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
Expand Down
10 changes: 10 additions & 0 deletions build.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Remove-Item -Force lib/auto/build.dart
New-Item -ItemType File -Path lib/auto/build.dart

$BRANCH = git rev-parse --abbrev-ref HEAD
$COMMIT_HASH = git rev-parse --short HEAD
$COMMIT_DATE = git show -s --format=%ci

"const String branch = '$BRANCH';" | Out-File -FilePath lib/auto/build.dart -Encoding utf8
"const String commitHash = '$COMMIT_HASH';" | Out-File -FilePath lib/auto/build.dart -Encoding utf8 -Append
"const String commitDate = '$COMMIT_DATE';" | Out-File -FilePath lib/auto/build.dart -Encoding utf8 -Append
9 changes: 9 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
rm -f lib/auto/build.dart
touch lib/auto/build.dart
BRANCH=$(git rev-parse --abbrev-ref HEAD)
COMMIT_HASH=$(git rev-parse --short HEAD)
COMMIT_DATE=$(git show -s --format=%ci)

echo "const String branch = '$BRANCH';" > lib/auto/build.dart
echo "const String commitHash = '$COMMIT_HASH';" >> lib/auto/build.dart
echo "const String commitDate = '$COMMIT_DATE';" >> lib/auto/build.dart
10 changes: 7 additions & 3 deletions lib/arc/arc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,16 @@ class Arc {
continue;
}

log('File name: $fileName');
if (fileName != null && fileName != '(signature)' && fileName != '(listfile)' && fileName != '(attributes)') {
if (fileName != '(signature)' && fileName != '(listfile)' && fileName != '(attributes)') {
files.add(fileName);
if(onFile != null) {
final file = mpqArchive.openFileEx(fileName, 0);
await onFile(fileName, file.read(file.size()));
try {
final size = file.size();
await onFile(fileName, file.read(size));
} catch (e) {
log('Skipping file $fileName: $e');
}
}
}
} on StormLibException catch (e) {
Expand Down
3 changes: 3 additions & 0 deletions lib/auto/build.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const String branch = 'v0.2.0';
const String commitHash = '705c17d';
const String commitDate = '2024-06-03 23:53:34 -0600';
7 changes: 7 additions & 0 deletions lib/context.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:retro/utils/git.dart';

class RetroContext {
static const String versionName = '0.2.0';
static const int versionCode = 0;
static late GitInfo git;
}
137 changes: 75 additions & 62 deletions lib/features/create/create_custom/create_custom_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,72 +26,85 @@ class _CreateCustomScreenState extends State<CreateCustomScreen> {
Widget build(BuildContext context) {
final theme = Theme.of(context);
final textTheme = theme.textTheme;
final viewModel =
Provider.of<CreateCustomViewModel>(context);
final finishViewModel =
Provider.of<CreateFinishViewModel>(context);
final viewModel = Provider.of<CreateCustomViewModel>(context);
final finishViewModel = Provider.of<CreateFinishViewModel>(context);
final i18n = AppLocalizations.of(context)!;

return CustomScaffold(
title: i18n.createCustomScreen_title,
subtitle: i18n.createCustomScreen_subtitle,
onBackButtonPressed: () {
viewModel.reset();
Navigator.of(context).pop();
},
content: Expanded(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: OutlinedButton(
onPressed: viewModel.onSelectFiles,
style: ElevatedButton.styleFrom(
minimumSize: const Size(200, 50),),
child:
Text(i18n.createCustomScreen_selectButton),),
),
Text(viewModel.path),
],
),
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'${i18n.createCustomScreen_fileToInsert}${viewModel.files.length}',
style: textTheme.titleMedium,
),
title: i18n.createCustomScreen_title,
subtitle: i18n.createCustomScreen_subtitle,
onBackButtonPressed: () {
viewModel.reset();
Navigator.of(context).pop();
},
content: Expanded(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: OutlinedButton(
onPressed: viewModel.onSelectFiles,
style: ElevatedButton.styleFrom(
minimumSize: const Size(200, 50),
),
child: Text(i18n.createCustomScreen_selectButton),
),
Expanded(
child: ListView.builder(
itemCount: viewModel.files.length,
itemBuilder: (context, index) {
return Text(p.relative(
viewModel.files[index].path,
from: viewModel.path,),);
},),),
ElevatedButton(
onPressed: viewModel.files.isNotEmpty &&
viewModel.path.isNotEmpty
? () {
finishViewModel.onAddCustomStageEntries(
viewModel.files, viewModel.path,);
viewModel.reset();
Navigator.of(context).popUntil(
ModalRoute.withName('/create_selection'),);
}
: null,
style: ElevatedButton.styleFrom(
minimumSize: Size(
MediaQuery.of(context).size.width * 0.5, 50,),),
child: Text(i18n.createCustomScreen_stageFiles),),
],
),),),);
),
Text(viewModel.path),
],
),
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'${i18n.createCustomScreen_fileToInsert}${viewModel.files.length}',
style: textTheme.titleMedium,
),
),
),
Expanded(
child: ListView.builder(
itemCount: viewModel.files.length,
itemBuilder: (context, index) {
return Text(
p.relative(
viewModel.files[index].path,
from: viewModel.path,
),
);
},
),
),
ElevatedButton(
onPressed: viewModel.files.isNotEmpty && viewModel.path.isNotEmpty
? () {
finishViewModel.onAddCustomStageEntries(
viewModel.files,
viewModel.path,
);
viewModel.reset();
Navigator.of(context).popUntil(
ModalRoute.withName('/create_selection'),
);
}
: null,
style: ElevatedButton.styleFrom(
minimumSize: Size(
MediaQuery.of(context).size.width * 0.5,
50,
),
),
child: Text(i18n.createCustomScreen_stageFiles),
),
],
),
),
),
);
}
}
17 changes: 12 additions & 5 deletions lib/features/create/create_finish/create_finish_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ class CreateFinishViewModel with ChangeNotifier {
notifyListeners();
}

onAddCustomTextureEntry(
void onAddCustomTextureEntry(
HashMap<String, List<Tuple2<File, TextureManifestEntry>>> replacementMap,
) {
for (final entry in replacementMap.entries) {
if (entries.containsKey(entry.key) &&
entries[entry.key] is CustomTexturesEntry) {
(entries[entry.key] as CustomTexturesEntry).pairs.addAll(entry.value);
(entries[entry.key]! as CustomTexturesEntry).pairs.addAll(entry.value);
} else if (entries.containsKey(entry.key)) {
throw Exception('Cannot add custom texture entry to existing entry');
} else {
Expand All @@ -124,18 +124,25 @@ class CreateFinishViewModel with ChangeNotifier {
notifyListeners();
}

void onAddFile(File file, String path) {
entries[path] = CustomStageEntry([file]);
totalFiles++;
currentState = AppState.changesStaged;
notifyListeners();
}

void onRemoveFile(File file, String path) {
if (entries.containsKey(path) && entries[path] is CustomStageEntry) {
(entries[path] as CustomStageEntry).files.remove(file);
(entries[path]! as CustomStageEntry).files.remove(file);
} else if (entries.containsKey(path) &&
entries[path] is CustomSequencesEntry) {
(entries[path] as CustomSequencesEntry).pairs.removeWhere(
(entries[path]! as CustomSequencesEntry).pairs.removeWhere(
(pair) =>
pair.item1.path == file.path || pair.item2.path == file.path,
);
} else if (entries.containsKey(path) &&
entries[path] is CustomTexturesEntry) {
(entries[path] as CustomTexturesEntry)
(entries[path]! as CustomTexturesEntry)
.pairs
.removeWhere((pair) => pair.item1.path == file.path);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'package:retro/otr/resource.dart';
import 'package:retro/otr/resource_type.dart';
import 'package:retro/otr/types/background.dart';
import 'package:retro/otr/types/texture.dart';
import 'package:retro/otr/version.dart';
import 'package:retro/utils/log.dart';
import 'package:retro/utils/path.dart' as p;
import 'package:tuple/tuple.dart';
Expand Down Expand Up @@ -170,8 +171,8 @@ Future<HashMap<String, ProcessedFilesInFolder>?> processFolder(
return null;
}

String manifestContents = await manifestFile.readAsString();
Map<String, dynamic> manifest = json.decode(manifestContents) as Map<String, dynamic>;
final manifestContents = await manifestFile.readAsString();
final manifest = json.decode(manifestContents) as Map<String, dynamic>;

// find all images in folder
final supportedExtensions = <String>['.png', '.jpeg', '.jpg'];
Expand All @@ -187,7 +188,7 @@ Future<HashMap<String, ProcessedFilesInFolder>?> processFolder(
p.normalize(texFile.path.split('$folderPath/').last.split('.').first);
if (manifest.containsKey(texPathRelativeToFolder)) {
final manifestEntry =
TextureManifestEntry.fromJson(manifest[texPathRelativeToFolder]);
TextureManifestEntry.fromJson(manifest[texPathRelativeToFolder] as Map<String, dynamic>);
// if it is, check if the file has changed
final texFileBytes = await texFile.readAsBytes();
final texFileHash = sha256.convert(texFileBytes).toString();
Expand Down Expand Up @@ -218,38 +219,32 @@ Future<HashMap<String, ProcessedFilesInFolder>?> processFolder(

Future<HashMap<String, TextureManifestEntry>?> processOTR(
Tuple2<List<String>, String> params) async {
try {
var fileFound = false;
final processedFiles = HashMap<String, TextureManifestEntry>();
final processedFiles = HashMap<String, TextureManifestEntry>();

// just use the first otr in the list for the directory name
final otrNameForOutputDirectory =
params.item1[0].split(Platform.pathSeparator).last.split('.').first;

// if folder we'll export to exists, delete it
final dir = Directory('${params.item2}/$otrNameForOutputDirectory');
if (dir.existsSync()) {
log('Deleting existing folder: ${params.item2}/$otrNameForOutputDirectory');
await dir.delete(recursive: true);
}
// just use the first otr in the list for the directory name
final otrNameForOutputDirectory =
params.item1[0].split(Platform.pathSeparator).last.split('.').first;

for (final otrPath in params.item1) {
log('Processing OTR: $otrPath');
final arcFile = Arc(otrPath);
// if folder we'll export to exists, delete it
final dir = Directory('${params.item2}/$otrNameForOutputDirectory');
if (dir.existsSync()) {
log('Deleting existing folder: ${params.item2}/$otrNameForOutputDirectory');
await dir.delete(recursive: true);
}

await arcFile.listItems(onFile: (String fileName, Uint8List data) async {
await processFile(fileName, data, '${params.item2}/$otrNameForOutputDirectory/$fileName', (TextureManifestEntry entry) {
processedFiles[fileName] = entry;
});
},);
arcFile.close();
}
for (final otrPath in params.item1) {
log('Processing OTR: $otrPath');
final arcFile = Arc(otrPath);

return processedFiles;
} on StormLibException catch (e) {
log('Failed to find next file: ${e.message}');
return null;
await arcFile.listItems(onFile: (String fileName, Uint8List data) async {
await processFile(fileName, data, '${params.item2}/$otrNameForOutputDirectory/$fileName', (TextureManifestEntry entry) {
processedFiles[fileName] = entry;
});
},);
arcFile.close();
}

return processedFiles.isEmpty ? null : processedFiles;
}

Future<bool> processFile(String fileName, Uint8List data, String outputPath, Function onProcessed) async {
Expand All @@ -269,6 +264,11 @@ Future<bool> processFile(String fileName, Uint8List data, String outputPath, Fun
final texture = Texture.empty();
texture.open(data);

// don't try to extract hd textures
if(texture.gameVersion == Version.roy){
break;
}

final pngBytes = texture.toPNGBytes();
final textureFile = File('$outputPath.png');
await textureFile.create(recursive: true);
Expand Down
Loading

0 comments on commit ac95511

Please sign in to comment.