Skip to content

Commit

Permalink
3.8.0 (#82)
Browse files Browse the repository at this point in the history
* init wip

* before autofac

* use autofac

* wip

* Rename optional tab to extras tab
Fix ugly checkbox spacing
Disable checkboxes when sims path is invalid

* No need to register views anymore

* Add validation attributes to the sims path property

* Tweak the required attribute to not pop on initial load

* Add an extra check to disable/enable the cheats checkbox

* wip notification

* notification easing

* Give the notification a border

* Fix extras tab dimensions?

* wip

* Remove unnecessary panel
Move margin from stackpanel to parent dockpanel

* Clarify unlock cheats tooltip

* point the wiki button to the extras wiki

* give the notification a margin

* wip

* Dismiss notification animation

* create resolutionpatchservice, and uninstallservice
move interfaces to interface folder

* Replace the images static class with the ImagesService

* Add more information of the patch progress to the progress bar

* Fix a bug where you patch, apply the Unlock Cheats patch, uninstall, and the Unlock Cheats checkbox still thinks the Unlock Cheats patch is applied

* Turn wrapperutility into wrapperservice
Delete the Utility project

* update version

* Fix image patching on non-windows machines

* Fix unlock cheat tool tip text

Co-authored-by: Margen67 <[email protected]>

* Change the notification to match the sims's popup box

---------

Co-authored-by: Margen67 <[email protected]>
  • Loading branch information
FaithBeam and Margen67 authored Jan 13, 2024
1 parent a5c87b3 commit 29925ef
Show file tree
Hide file tree
Showing 109 changed files with 2,390 additions and 1,549 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: .NET

env:
PACK_ID: Sims1WidescreenPatcher
PACK_VER: 3.7.2
PACK_VER: 3.8.0-beta.2

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# The Sims 1 Widescreen Patcher
# The Sims 1 Widescreen Patcher

This program patches **The Sims 1** to a custom resolution.

Expand Down
19 changes: 19 additions & 0 deletions Sims1WidescreenPatcher.Core/Events/NewProgressEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Sims1WidescreenPatcher.Core.Events;

public class NewProgressEventArgs
{
public double Progress { get; }
public string Status { get; }
public string Status2 { get; }

public NewProgressEventArgs(double progress) : this(progress, string.Empty, string.Empty)
{
}

public NewProgressEventArgs(double progress, string status, string status2)
{
Progress = progress;
Status = status;
Status2 = status2;
}
}
6 changes: 6 additions & 0 deletions Sims1WidescreenPatcher.Core/Events/NewUninstallEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Sims1WidescreenPatcher.Core.Events;

public class NewUninstallEventArgs : EventArgs
{

}
17 changes: 17 additions & 0 deletions Sims1WidescreenPatcher.Core/Factories/CheckboxViewModelFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using ReactiveUI;
using Sims1WidescreenPatcher.Core.ViewModels;

namespace Sims1WidescreenPatcher.Core.Factories;

public class CheckboxViewModelFactory: UserControlViewModelCreator
{
public override IReactiveObject Create(string label)
{
return new CheckboxViewModel(label, "");
}

public IReactiveObject Create(string label, string tooltip)
{
return new CheckboxViewModel(label, tooltip);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using ReactiveUI;

namespace Sims1WidescreenPatcher.Core.Factories;

public interface IUserControlViewModelCreator
{
IReactiveObject Create(string arg0);
}
6 changes: 6 additions & 0 deletions Sims1WidescreenPatcher.Core/Factories/ImageJobFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Sims1WidescreenPatcher.Core.Factories;

public class ImageJobFactory
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using ReactiveUI;

namespace Sims1WidescreenPatcher.Core.Factories;

public abstract class UserControlViewModelCreator : IUserControlViewModelCreator
{
public abstract IReactiveObject Create(string arg0);
}
46 changes: 46 additions & 0 deletions Sims1WidescreenPatcher.Core/Models/AppState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using ReactiveUI;

namespace Sims1WidescreenPatcher.Core.Models;

public class AppState : ReactiveObject, IAppState
{
private string? _simsExePath;
private Resolution? _resolution;

public string? SimsExePath
{
get => _simsExePath;
set => this.RaiseAndSetIfChanged(ref _simsExePath, value);
}

public bool SimsExePathExists => File.Exists(SimsExePath);

public string SimsBackupPath
{
get
{
if (string.IsNullOrWhiteSpace(SimsExePath))
{
return "";
}
const string backupName = "Sims Backup.exe";
var parent = Directory.GetParent(SimsExePath)!.ToString();
return Path.Combine(parent, backupName);
}
}

public bool SimsBackupExists
{
get
{
var backup = SimsBackupPath;
return !string.IsNullOrWhiteSpace(backup) && File.Exists(backup);
}
}

public Resolution? Resolution
{
get => _resolution;
set => this.RaiseAndSetIfChanged(ref _resolution, value);
}
}
39 changes: 39 additions & 0 deletions Sims1WidescreenPatcher.Core/Models/BaseImageProcessingJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using ImageMagick;

namespace Sims1WidescreenPatcher.Core.Models;

public abstract class BaseImageProcessingJob
{
public byte[]? ImageBytes;
public string? Output;
public string? BaseImageName;
public int Width;
public int Height;

/// <summary>
/// Overrides should call this base method before continuing
/// </summary>
public virtual void Run()
{
if (!string.IsNullOrWhiteSpace(Output))
{
BaseImageName = Path.GetFileName(Output);
}
var destDir = Path.GetDirectoryName(Output);
if (destDir == null || Directory.Exists(destDir)) return;
Directory.CreateDirectory(destDir);
if (ImageBytes is null || string.IsNullOrWhiteSpace(Output))
{
throw new Exception("ImagesBytes or Output is null");
}
}

protected static void SetCommonBmpSettings(MagickImage bmp)
{
bmp.Depth = 8;
bmp.Settings.Compression = CompressionMethod.RLE;
bmp.Settings.Format = MagickFormat.Bmp3;
bmp.ColorType = ColorType.Palette;
bmp.Alpha(AlphaOption.Off);
}
}
43 changes: 43 additions & 0 deletions Sims1WidescreenPatcher.Core/Models/CheckboxSelectionSnapshot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Sims1WidescreenPatcher.Core.ViewModels;

namespace Sims1WidescreenPatcher.Core.Models;

public class CheckboxSelectionSnapshot : IEquatable<CheckboxSelectionSnapshot>
{
private readonly bool[] _vms;

public CheckboxSelectionSnapshot(params bool[] vms)
{
_vms = vms;
}

public bool Equals(CheckboxSelectionSnapshot? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (_vms.Length != other._vms.Length) return false;

for (int i = 0; i < _vms.Length; i++)
{
if (_vms[i] != other._vms[i])
{
return false;
}
}

return true;
}

public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CheckboxSelectionSnapshot)obj);
}

public override int GetHashCode()
{
return _vms.GetHashCode();
}
}
27 changes: 27 additions & 0 deletions Sims1WidescreenPatcher.Core/Models/CompositeImageJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using ImageMagick;

namespace Sims1WidescreenPatcher.Core.Models;

public class CompositeImageJob : BaseImageProcessingJob
{
/// <summary>
/// Color should be a hex color code like #113355
/// </summary>
public string? Color;

public override void Run()
{
base.Run();

if (string.IsNullOrWhiteSpace(Color))
{
throw new Exception("Color is null");
}

using var image = new MagickImage(ImageBytes!);
using var background = new MagickImage(new MagickColor(Color), Width, Height);
background.Composite(image, Gravity.Center);
SetCommonBmpSettings(background);
background.Write(Output!);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Sims1WidescreenPatcher.Utilities.Models;
namespace Sims1WidescreenPatcher.Core.Models;

public interface IWrapper
{
Expand Down
10 changes: 10 additions & 0 deletions Sims1WidescreenPatcher.Core/Models/IAppState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Sims1WidescreenPatcher.Core.Models;

public interface IAppState
{
string? SimsExePath { get; set; }
bool SimsExePathExists { get; }
Resolution? Resolution { get; set; }
string SimsBackupPath { get; }
bool SimsBackupExists { get; }
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
using ImageMagick;

namespace Sims1WidescreenPatcher.Images.Models;
namespace Sims1WidescreenPatcher.Core.Models;

public class ScalePanelbackJob : BaseImageProcessingJob
public class ScalePanelBackJob : BaseImageProcessingJob
{
public ScalePanelbackJob(byte[] bytes, string output, int width, int height) : base(bytes, output, width, height)
{
}

public override void Run()
{
using var image = new MagickImage(ImageBytes);
base.Run();

using var image = new MagickImage(ImageBytes!);
var left = image.Clone(0, 0, 286, 100);
var middle = image.Clone(left.Width, 0, 500, 100);
var right = image.Clone(left.Width + middle.Width, 0, 18, 100);
Expand All @@ -24,6 +22,6 @@ public override void Run()
imageCollection.Add(right);
var merged = imageCollection.Merge();
SetCommonBmpSettings((MagickImage)merged);
merged.Write(Output);
merged.Write(Output!);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
using ImageMagick;

namespace Sims1WidescreenPatcher.Images.Models;
namespace Sims1WidescreenPatcher.Core.Models;

public class ScaleTallSubPanelJob : BaseImageProcessingJob
{
public ScaleTallSubPanelJob(byte[] bytes, string output, int width, int height) : base(bytes, output, width, height)
{
}

public override void Run()
{
using var image = new MagickImage(ImageBytes, MagickFormat.Tga);
base.Run();

using var image = new MagickImage(ImageBytes!, MagickFormat.Tga);
image.Resize(new MagickGeometry(Width, Height) { IgnoreAspectRatio = true });
image.Depth = 32;
image.Settings.Compression = CompressionMethod.RLE;
image.Settings.Format = MagickFormat.Tga;
image.Write(Output);
image.Write(Output!);
}
}
59 changes: 59 additions & 0 deletions Sims1WidescreenPatcher.Core/Services/CheatsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Sims1WidescreenPatcher.Core.Models;
using Sims1WidescreenPatcher.Core.Services.Interfaces;

namespace Sims1WidescreenPatcher.Core.Services;

public class CheatsService : ICheatsService
{
private const string DisableCheatsPattern = "00 56 90 90";
private const string EnableCheatsPattern = "00 56 75 04";
private readonly IAppState _appState;
private readonly IPatchFileService _patchFileService;

public CheatsService(IAppState appState, IPatchFileService patchFileService)
{
_appState = appState;
_patchFileService = patchFileService;
}

public bool CheatsEnabled()
{
var (found, _, _) = _patchFileService.FindPattern(_appState.SimsExePath, DisableCheatsPattern);
return found;
}

/// <summary>
/// Determine if the sims exe can be patched to enable all cheats
/// </summary>
/// <returns></returns>
public bool CanEnableCheats()
{
var (disablePatternFound, _, _) = _patchFileService.FindPattern(_appState.SimsExePath, DisableCheatsPattern);
var (enablePatternFound, _, _) = _patchFileService.FindPattern(_appState.SimsExePath,EnableCheatsPattern);
return disablePatternFound || enablePatternFound;
}

public void EnableCheats()
{
EditSimsExe(EnableCheatsPattern, new Tuple<byte, byte>(144, 144));
}

public void DisableCheats()
{
EditSimsExe(DisableCheatsPattern, new Tuple<byte, byte>(117, 4));
}

private void EditSimsExe(string pattern, Tuple<byte, byte> replacementBytes)
{
var (found, offset, bytes) = _patchFileService.FindPattern(_appState.SimsExePath, pattern);
if (!found)
{
return;
}

bytes![offset + 2] = replacementBytes.Item1;
bytes[offset + 2 + 1] = replacementBytes.Item2;

_patchFileService.WriteChanges(_appState.SimsExePath, bytes);
}
}
Loading

0 comments on commit 29925ef

Please sign in to comment.