Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixes for the version 4 initial release #915

Merged
merged 18 commits into from
Jul 9, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ public class BitmapFontImporter : ContentImporter<ContentImporterResult<BitmapFo
{
public override ContentImporterResult<BitmapFontFileContent> Import(string filename, ContentImporterContext context)
{
context.Logger.LogMessage("Importing FNT file: {0}", filename);

using FileStream stream = File.OpenRead(filename);
var bmfFile = BitmapFontFileReader.Read(stream);
return new ContentImporterResult<BitmapFontFileContent>(filename, bmfFile);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ public override BitmapFontProcessorResult Process(ContentImporterResult<BitmapFo
try
{
BitmapFontFileContent bmfFile = importerResult.Data;
context.Logger.LogMessage("Processing BMFont");
var result = new BitmapFontProcessorResult(bmfFile);

foreach (var fontPage in bmfFile.Pages)
foreach (var page in bmfFile.Pages)
{
var assetName = Path.GetFileNameWithoutExtension(fontPage);
context.Logger.LogMessage("Expected texture asset: {0}", assetName);
result.TextureAssets.Add(assetName);

context.AddDependency(Path.GetFileName(page));
result.TextureAssets.Add(Path.GetFileNameWithoutExtension(page));
}

return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
// See LICENSE file in the project root for full license information.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using MonoGame.Extended.BitmapFonts;
using MonoGame.Extended.Content.BitmapFonts;
using MonoGame.Extended.Graphics;

namespace MonoGame.Extended.Content.ContentReaders;
Expand All @@ -17,35 +14,53 @@ public class BitmapFontContentReader : ContentTypeReader<BitmapFont>
{
protected override BitmapFont Read(ContentReader reader, BitmapFont existingInstance)
{
if (existingInstance is not null)
var textureCount = reader.ReadInt32();
var textures = new Texture2D[textureCount];

for (int i = 0; i < textureCount; i++)
{
return existingInstance;
var textureName = reader.ReadString();
textures[i] = reader.ContentManager.Load<Texture2D>(reader.GetRelativeAssetName(textureName));
}

var bmfFile = BitmapFontFileReader.Read((FileStream)reader.BaseStream);

var textures =
bmfFile.Pages.Select(page => reader.ContentManager.Load<Texture2D>(reader.GetRelativeAssetName(page)))
.ToArray();
var fontName = reader.ReadString();
var fontSize = reader.ReadInt16();
var lineHeight = reader.ReadUInt16();

var characterCount = reader.ReadInt32();
var characters = new Dictionary<int, BitmapFontCharacter>();
foreach (var charBlock in bmfFile.Characters)

for (int i = 0; i < characterCount; i++)
{
var texture = textures[charBlock.Page];
var region = new Texture2DRegion(texture, charBlock.X, charBlock.Y, charBlock.Width, charBlock.Height);
var character = new BitmapFontCharacter((int)charBlock.ID, region, charBlock.XOffset, charBlock.YOffset, charBlock.XAdvance);
var id = reader.ReadUInt32();
var page = reader.ReadByte();
var x = reader.ReadUInt16();
var y = reader.ReadUInt16();
var width = reader.ReadUInt16();
var height = reader.ReadUInt16();
var xOffset = reader.ReadInt16();
var yOffset = reader.ReadInt16();
var xAdvance = reader.ReadInt16();

var characterRegion = new Texture2DRegion(textures[page], x, y, width, height);
var character = new BitmapFontCharacter((char)id, characterRegion, xOffset, yOffset, xAdvance);
characters.Add(character.Character, character);
}

var kerningCount = reader.ReadInt32();

foreach (var kerningBlock in bmfFile.Kernings)
for (int i = 0; i < kerningCount; i++)
{
if (characters.TryGetValue((int)kerningBlock.First, out var character))
var first = reader.ReadUInt32();
var second = reader.ReadUInt32();
var amount = reader.ReadInt16();

if (characters.TryGetValue((int)first, out var character))
{
character.Kernings.Add((int)kerningBlock.Second, kerningBlock.Amount);
character.Kernings.Add((int)second, amount);
}
}

return new BitmapFont(bmfFile.FontName, bmfFile.Info.FontSize, bmfFile.Common.LineHeight, characters.Values);
return new BitmapFont(fontName, fontSize, lineHeight, characters.Values);
}
}
51 changes: 35 additions & 16 deletions source/MonoGame.Extended/Input/KeyboardExtended.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,41 @@
using Microsoft.Xna.Framework.Input;

namespace MonoGame.Extended.Input
namespace MonoGame.Extended.Input;

/// <summary>
/// Represents keyboard input.
/// </summary>
/// <remarks>
/// This is an extended version of the default <see cref="Microsoft.Xna.Framework.Input.Keyboard"/> class
/// which offers internal tracking of both the previous and current state of keyboard input.
/// </remarks>
public static class KeyboardExtended
{
public static class KeyboardExtended
{
// TODO: This global static state was a horrible idea.
private static KeyboardState _currentKeyboardState;
private static KeyboardState _previousKeyboardState;
private static KeyboardState _currentKeyboardState;
private static KeyboardState _previousKeyboardState;

public static KeyboardStateExtended GetState()
{
return new KeyboardStateExtended(_currentKeyboardState, _previousKeyboardState);
}
/// <summary>
/// Gets the state of keyboard input.
/// </summary>
/// <returns>
/// A <see cref="KeyboardStateExtended"/> value that represents the state of keyboard input.
/// </returns>
public static KeyboardStateExtended GetState()
{
return new KeyboardStateExtended(_currentKeyboardState, _previousKeyboardState);
}

public static void Refresh()
{
_previousKeyboardState = _currentKeyboardState;
_currentKeyboardState = Keyboard.GetState();
}
/// <summary>
/// Updates the <see cref="KeyboardExtended"/>
/// </summary>
/// <remarks>
/// This internally will overwrite the source data for the previous state with the current state, then get the
/// current state from the keyboard input. This should only be called once per update cycle. Calling it more
/// than once per update cycle can result in the cached previous state being overwritten with invalid data.
/// </remarks>
public static void Update()
{
_previousKeyboardState = _currentKeyboardState;
_currentKeyboardState = Keyboard.GetState();
}
}
}
119 changes: 98 additions & 21 deletions source/MonoGame.Extended/Input/KeyboardStateExtended.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,38 @@
using System;
using System.Linq;
// Copyright (c) Craftwork Games. All rights reserved.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.

using System;
using Microsoft.Xna.Framework.Input;

namespace MonoGame.Extended.Input
{
/// <summary>
/// Represents the state of keyboard input
/// </summary>
/// <remarks>
/// This is an extended version of the base <see cref="Microsoft.Xna.Framework.Input.KeyboardState"/> struct
/// that provides utility for checking the state differences between the previous and current state.
/// </remarks>
public struct KeyboardStateExtended
{
private KeyboardState _currentKeyboardState;
private KeyboardState _previousKeyboardState;

/// <summary>
/// Initializes a new instance of the <see cref="KeyboardStateExtended"/> value.
/// </summary>
/// <param name="currentKeyboardState">The state of keyboard input during the current update cycle.</param>
/// <param name="previousKeyboardState">The state of keyboard input during the previous update cycle.</param>
public KeyboardStateExtended(KeyboardState currentKeyboardState, KeyboardState previousKeyboardState)
{
_currentKeyboardState = currentKeyboardState;
_previousKeyboardState = previousKeyboardState;
}

/// <summary>
/// Gets a value that indicates whether the caps lock key is down during the current state.
/// </summary>
public bool CapsLock
{
#if FNA
Expand All @@ -23,6 +41,9 @@ public bool CapsLock
get { return _currentKeyboardState.CapsLock; }
#endif
}
/// <summary>
/// Gets a value that indicates whether the num lock key is down during the current state.
/// </summary>
public bool NumLock
{
#if FNA
Expand All @@ -31,44 +52,100 @@ public bool NumLock
get { return _currentKeyboardState.NumLock; }
#endif
}

/// <summary>
/// Returns a value that indicates whether either the left or right shift key is down during the current state.
/// </summary>
/// <returns>
/// <see langword="true"/> if either the left or right shift key is down during the current state; otherwise,
/// <see langword="false"/>.
/// </returns>
public bool IsShiftDown() => _currentKeyboardState.IsKeyDown(Keys.LeftShift) || _currentKeyboardState.IsKeyDown(Keys.RightShift);

/// <summary>
/// Returns a value that indicates whether either the left or right control key is down during the current
/// state.
/// </summary>
/// <returns>
/// <see langword="true"/> if either the left or right control key is down during the current state; otherwise,
/// <see langword="false"/>.
/// </returns>
public bool IsControlDown() => _currentKeyboardState.IsKeyDown(Keys.LeftControl) || _currentKeyboardState.IsKeyDown(Keys.RightControl);

/// <summary>
/// Returns a value that indicates whether either the left or righ talt key is currently pressed down.
/// </summary>
/// <returns></returns>
public bool IsAltDown() => _currentKeyboardState.IsKeyDown(Keys.LeftAlt) || _currentKeyboardState.IsKeyDown(Keys.RightAlt);
public bool IsKeyDown(Keys key) => _currentKeyboardState.IsKeyDown(key);
public bool IsKeyUp(Keys key) => _currentKeyboardState.IsKeyUp(key);
public Keys[] GetPressedKeys() => _currentKeyboardState.GetPressedKeys();
public void GetPressedKeys(Keys[] keys) => _currentKeyboardState.GetPressedKeys(keys);


/// <summary>
/// Gets whether the given key was down on the previous state, but is now up.
/// Returns a value that indicates if the specified key is down during the current state.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>true if the key was released this state-change, otherwise false.</returns>
[Obsolete($"Deprecated in favor of {nameof(IsKeyReleased)}")]
public bool WasKeyJustDown(Keys key) => _previousKeyboardState.IsKeyDown(key) && _currentKeyboardState.IsKeyUp(key);
/// <returns>
/// <see langword="true"/> if the key is down during the current state; otherwise, <see langword="false"/>.
/// </returns>
public bool IsKeyDown(Keys key) => _currentKeyboardState.IsKeyDown(key);

/// <summary>
/// Gets whether the given key was up on the previous state, but is now down.
/// Returns a value that indicates if the specified key is up during the current state.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>true if the key was pressed this state-change, otherwise false.</returns>
[Obsolete($"Deprecated in favor of {nameof(IsKeyPressed)}")]
public bool WasKeyJustUp(Keys key) => _previousKeyboardState.IsKeyUp(key) && _currentKeyboardState.IsKeyDown(key);
/// <returns>
/// <see langword="true"/> if the key is up during the current state; otherwise, <see langword="false"/>.
/// </returns>
public bool IsKeyUp(Keys key) => _currentKeyboardState.IsKeyUp(key);

/// <summary>
/// Returns the total number of keys down during the current state.
/// </summary>
public int GetPressedKeyCount => _currentKeyboardState.GetPressedKeyCount();

/// <summary>
/// Returns an array of all keys that are down during the current state.
/// </summary>
/// <returns>
/// An array of <see cref="Keys"/> values that represent each key that is down during the current state.
/// </returns>
public Keys[] GetPressedKeys() => _currentKeyboardState.GetPressedKeys();

/// <summary>
/// Gets whether the given key was down on the previous state, but is now up.
/// Fills an existing array with the keys pressed during the current state.
/// </summary>
/// <param name="keys">An existing array to fill with the pressed keys.</param>
/// <exception cref="ArgumentNullException">
/// Thrown if the <paramref name="keys"/> parameter is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if the array provided by the <paramref name="keys"/> parameter is not large enough to fit all
/// pressed keys. Use <see cref="GetPressedKeyCount"/> to determine the total number of elements.
/// </exception>
public void GetPressedKeys(Keys[] keys) => _currentKeyboardState.GetPressedKeys(keys);

/// <summary>
/// Returns whether the given key was down during previous state, but is now up.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>true if the key was released this state-change, otherwise false.</returns>
public readonly bool IsKeyReleased(Keys key) => _previousKeyboardState.IsKeyDown(key) && _currentKeyboardState.IsKeyUp(key);
/// <returns>
/// <see langword="true"/> if the key was released this state-change, otherwise <see langword="false"/>.
/// </returns>
public readonly bool WasKeyReleased(Keys key) => _previousKeyboardState.IsKeyDown(key) && _currentKeyboardState.IsKeyUp(key);

/// <summary>
/// Gets whether the given key was up on the previous state, but is now down.
/// Returns whether the given key was up during previous state, but is now down.
/// </summary>
/// <param name="key">The key to check.</param>
/// <returns>true if the key was pressed this state-change, otherwise false.</returns>
public readonly bool IsKeyPressed(Keys key) => _previousKeyboardState.IsKeyUp(key) && _currentKeyboardState.IsKeyDown(key);
/// <returns>
/// <see langword="true"/> if the key was pressed this state-change, otherwise <see langword="false"/>.
/// </returns>
public readonly bool WasKeyPressed(Keys key) => _previousKeyboardState.IsKeyUp(key) && _currentKeyboardState.IsKeyDown(key);

/// <summary>
/// Returns whether any key was pressed down on the previous state.
/// </summary>
/// <returns>
/// <see langword="true"/> if any key was pressed during the previous state; otherwise, <see langword="false"/>.
/// </returns>
public bool WasAnyKeyJustDown() => _previousKeyboardState.GetPressedKeyCount() > 0;
}
}
Loading
Loading