diff --git a/onboard/DevcadeClient.cs b/onboard/DevcadeClient.cs index c81654e..55b762f 100644 --- a/onboard/DevcadeClient.cs +++ b/onboard/DevcadeClient.cs @@ -35,6 +35,8 @@ public class DevcadeClient { private readonly string _apiDomain; + // Basically a semaphore for communicating between the main thread (doing the menu animations) + // and the thread that loads the game. public bool DownloadFailed = false; public DevcadeClient() diff --git a/onboard/Game1.cs b/onboard/Game1.cs index 9606b99..dd8446d 100644 --- a/onboard/Game1.cs +++ b/onboard/Game1.cs @@ -50,6 +50,9 @@ private enum MenuState // To indicate that there was a problem running the game private bool _errorLoading = false; + // If we can't fetch the game list (like if the API is down) + private bool _cantFetch = false; + public Game1() { _graphics = new GraphicsDeviceManager(this); @@ -92,8 +95,16 @@ protected override void LoadContent() loadingSpin = Content.Load("loadingSheet"); // TODO: use this.Content to load your game content here - _mainMenu.gameTitles = _client.GetGames(); - _mainMenu.setCards(_client, GraphicsDevice); + try + { + _mainMenu.gameTitles = _client.GetGames(); + _mainMenu.setCards(_client, GraphicsDevice); + } catch (System.AggregateException e) + { + Console.WriteLine($"Failed to fetch games: {e}"); + state = MenuState.Loading; + _cantFetch = true; + } } protected override void Update(GameTime gameTime) @@ -126,6 +137,27 @@ protected override void Update(GameTime gameTime) break; case MenuState.Loading: + + if (_cantFetch) + { + if (myState.IsKeyDown(Keys.Space) || (Input.GetButton(1, Input.ArcadeButtons.Menu) && Input.GetButton(2, Input.ArcadeButtons.Menu))) + { + try { + _mainMenu.clearGames(); + _mainMenu.gameTitles = _client.GetGames(); + _mainMenu.setCards(_client, GraphicsDevice); + _cantFetch = false; + state = MenuState.Input; + } catch (System.AggregateException e) + { + Console.WriteLine($"Failed to fetch games: {e}"); + state = MenuState.Loading; + _cantFetch = true; + } + + } + } + _errorLoading = false; // Clear error loading if we successfully load. // Check for process that matches last launched game and display loading screen if it's running // This can be done easier by keeping a reference to the process spawned and .HasExited property... @@ -154,6 +186,21 @@ protected override void Update(GameTime gameTime) _mainMenu.descFadeOut(gameTime); _mainMenu.cardFadeIn(gameTime); + if (myState.IsKeyDown(Keys.Space) || (Input.GetButton(1, Input.ArcadeButtons.Menu) && Input.GetButton(2, Input.ArcadeButtons.Menu))) + { + _mainMenu.clearGames(); + try + { + _mainMenu.gameTitles = _client.GetGames(); + _mainMenu.setCards(_client, GraphicsDevice); + } catch (System.AggregateException e) + { + Console.WriteLine($"Failed to fetch games: {e}"); + state = MenuState.Loading; + _cantFetch = true; + } + } + if (((myState.IsKeyDown(Keys.Down)) || // Keyboard down Input.GetButton(1, Input.ArcadeButtons.StickDown) || // or joystick down Input.GetButton(2, Input.ArcadeButtons.StickDown))) // of either player @@ -243,6 +290,8 @@ protected override void Draw(GameTime gameTime) case MenuState.Loading: _mainMenu.drawLoading(_spriteBatch, loadingSpin, fadeColor); _mainMenu.drawTitle(_spriteBatch, titleTextureWhite, fadeColor); + if (_cantFetch) + _mainMenu.drawError(_spriteBatch, _devcadeMenuBig); break; } diff --git a/onboard/Menu.cs b/onboard/Menu.cs index d023161..fee41f1 100644 --- a/onboard/Menu.cs +++ b/onboard/Menu.cs @@ -59,9 +59,13 @@ public void updateDims(GraphicsDeviceManager _graphics) // Empties the gameTitles and cards lists. Called when the reload buttons are pressed public void clearGames() { + try { gameTitles.Clear(); cards.Clear(); itemSelected = 0; + } catch (System.NullReferenceException e) { + Console.WriteLine($"No game titles or cards yet. {e}"); + } } public void setCards(DevcadeClient _client, GraphicsDevice graphics) @@ -176,8 +180,8 @@ public void drawTitle(SpriteBatch _spriteBatch, Texture2D titleTexture, float co public void drawInstructions(SpriteBatch _spriteBatch, SpriteFont font) { - List instructions = wrapText("Press the Red button to play!", 25); - float instructSize = font.MeasureString("Press the Red button to play!").Y; + List instructions = wrapText("Press the Red button to play! Press both Black Buttons to refresh", 25); + float instructSize = font.MeasureString("Press the Red button to play! Press both Black Buttons to refresh").Y; int lineNum = 0; foreach (string line in instructions) @@ -192,6 +196,27 @@ public void drawInstructions(SpriteBatch _spriteBatch, SpriteFont font) } } + + public void drawError(SpriteBatch _spriteBatch, SpriteFont font) + { + string error = "Error: Could not get game list. Is API Down? Press both black buttons to reload."; + List instructions = wrapText(error, 25); + float instructSize = font.MeasureString(error).Y; + int lineNum = 0; + + foreach (string line in instructions) + { + writeString(_spriteBatch, + font, + line, + new Vector2(_sWidth / 2.0f, (int)(500 * scalingAmount) + (instructSize * lineNum)), // 500 is the height of the title, this string goes right beneath that + 1f, + Color.Red + ); + lineNum++; + } + } + public void drawLoading(SpriteBatch _spriteBatch, Texture2D loadingSpin, float col) { if (loadingCol > 4) @@ -339,6 +364,22 @@ public static List wrapText(string desc, int lineLimit) return lines; } + public void writeString(SpriteBatch _spriteBatch, SpriteFont font, string str, Vector2 pos, float opacity, Color color) + { + Vector2 strSize = font.MeasureString(str); + + _spriteBatch.DrawString(font, + str, + pos, + color, + 0f, + new Vector2(strSize.X / 2, strSize.Y / 2), + (float)(1f * scalingAmount), + SpriteEffects.None, + 0f + ); + } + public void writeString(SpriteBatch _spriteBatch, SpriteFont font, string str, Vector2 pos, float opacity) { Vector2 strSize = font.MeasureString(str);