/// <summary> /// Appends an abbreviation to the given zscii text. /// </summary> /// <param name="zcharacter"> /// The zcharacter. /// </param> /// <param name="calledRecursively"> /// A value which indicates whether the method was called recursively. /// </param> /// <param name="zcharacters"> /// The zcharacters. /// </param> /// <param name="zsciiText"> /// The zscii text. /// </param> protected void AppendAbbreviation(byte zcharacter, bool calledRecursively, ref ImmutableStack<byte> zcharacters, ref ImmutableStack<Zscii> zsciiText) { if (calledRecursively) { this.FrontEnd.ErrorNotification(ErrorCondition.NestedAbbreviation, "Nested abbreviation detected."); return; } if (zcharacters != null) { var abbreviationNumber = ((zcharacter - 1) * 32) + zcharacters.Top; zcharacters = zcharacters.Tail; var abbreviationsTableAddress = this.Memory.ReadWord(24); var abbreviationAddress = 2 * this.Memory.ReadWord(abbreviationsTableAddress + (2 * abbreviationNumber)); var abbreviation = this.ZCharactersToZscii(true, this.EncodedTextToZCharacters(ref abbreviationAddress)); foreach (var zsciiCharacter in abbreviation.Enumerable()) { zsciiText = zsciiText.Add(zsciiCharacter); } } }
/// <summary> /// Adds an alphabet shift to z-characters. /// </summary> /// <param name="neededAlphabet"> /// The needed alphabet. /// </param> /// <param name="zsciiText"> /// The zscii text following the alphabet shift. /// </param> /// <param name="lockedAlphabet"> /// The locked alphabet. /// </param> /// <param name="characters"> /// The z-characters. /// </param> protected override void AddAlphabetShiftToZCharacters(byte neededAlphabet, ImmutableStack<Zscii> zsciiText, ref byte lockedAlphabet, ref ImmutableStack<byte> characters) { characters = characters.Add((byte)(neededAlphabet + 3)); }
/// <summary> /// Adds an alphabet shift to z-characters. /// </summary> /// <param name="neededAlphabet"> /// The needed alphabet. /// </param> /// <param name="zsciiText"> /// The zscii text following the alphabet shift. /// </param> /// <param name="lockedAlphabet"> /// The locked alphabet. /// </param> /// <param name="characters"> /// The z-characters. /// </param> protected virtual void AddAlphabetShiftToZCharacters(byte neededAlphabet, ImmutableStack<Zscii> zsciiText, ref byte lockedAlphabet, ref ImmutableStack<byte> characters) { // bug: if next character is newline, space, etc... var shiftCharacter = (byte)(((3 + neededAlphabet - lockedAlphabet) % 3) + 1); if (zsciiText != null) { var nextIndex = this.GetZsciiAlphabetIndex(zsciiText.Top); var nextNeededAlphabet = (byte)((nextIndex == -1) ? 2 : nextIndex / 26); if (nextNeededAlphabet == neededAlphabet) { shiftCharacter += 2; lockedAlphabet = neededAlphabet; } } characters = characters.Add(shiftCharacter); }
/// <summary> /// Converts a zscii character to z-characters. /// </summary> /// <param name="zsciiCharacter"> /// The zscii character. /// </param> /// <param name="zsciiText"> /// The zscii text following the zscii character. /// </param> /// <param name="lockedAlphabet"> /// The locked alphabet. /// </param> /// <param name="characters"> /// The z-characters to add the results to. /// </param> /// <remarks> /// Newline is now part of the zscii alphabet. /// </remarks> protected virtual void ZsciiCharacterToZCharacters(Zscii zsciiCharacter, ImmutableStack<Zscii> zsciiText, ref byte lockedAlphabet, ref ImmutableStack<byte> characters) { switch (zsciiCharacter) { case Zscii.Null: break; case Zscii.Space: characters = characters.Add((byte)0); break; case Zscii.NewLine: characters = characters.Add((byte)1); break; default: this.ZsciiAlphabetCharacterToZCharacters(zsciiCharacter, zsciiText, ref lockedAlphabet, ref characters); break; } }
/// <summary> /// Converts a zscii alphabet character to z-characters. /// </summary> /// <param name="zsciiCharacter"> /// The zscii character. /// </param> /// <param name="zsciiText"> /// The zscii text. /// </param> /// <param name="lockedAlphabet"> /// The locked alphabet. /// </param> /// <param name="characters"> /// The z-characters. /// </param> protected void ZsciiAlphabetCharacterToZCharacters(Zscii zsciiCharacter, ImmutableStack<Zscii> zsciiText, ref byte lockedAlphabet, ref ImmutableStack<byte> characters) { var zsciiAlphabetIndex = this.GetZsciiAlphabetIndex(zsciiCharacter); var neededAlphabet = (byte)((zsciiAlphabetIndex == -1) ? 2 : zsciiAlphabetIndex / 26); if (neededAlphabet != lockedAlphabet) { this.AddAlphabetShiftToZCharacters(neededAlphabet, zsciiText, ref lockedAlphabet, ref characters); } if (zsciiAlphabetIndex > -1) { characters = characters.Add((byte)((zsciiAlphabetIndex % 26) + 6)); } else { characters = characters.Add((byte)6); characters = characters.Add((byte)((ushort)zsciiCharacter / 32)); characters = characters.Add((byte)((ushort)zsciiCharacter & 31)); } }
/// <summary> /// Converts z-characters to zscii text. /// </summary> /// <param name="calledRecursively"> /// A value which indicates whether the method was called recursively. /// </param> /// <param name="zcharacter"> /// The zcharacter. /// </param> /// <param name="currentAlphabet"> /// The current alphabet. /// </param> /// <param name="nextAlphabet"> /// The next alphabet. /// </param> /// <param name="lockedAlphabet"> /// The locked alphabet. /// </param> /// <param name="zcharacters"> /// The zcharacters. /// </param> /// <param name="zsciiText"> /// The zscii text. /// </param> protected virtual void ZCharactersToZscii(bool calledRecursively, byte zcharacter, byte currentAlphabet, ref byte nextAlphabet, ref byte lockedAlphabet, ref ImmutableStack<byte> zcharacters, ref ImmutableStack<Zscii> zsciiText) { switch (zcharacter) { case 0: zsciiText = zsciiText.Add(Zscii.Space); break; case 1: zsciiText = zsciiText.Add(Zscii.NewLine); break; case 2: case 3: nextAlphabet = (byte)((lockedAlphabet + zcharacter - 1) % 3); break; case 4: case 5: nextAlphabet = lockedAlphabet = (byte)((lockedAlphabet + zcharacter) % 3); break; default: if (zcharacter == 6 && currentAlphabet == 2) { if (zcharacters.Count() > 1) { zsciiText = zsciiText.Add((Zscii)((zcharacters.Top * 32) + zcharacters.Tail.Top)); zcharacters = zcharacters.Tail.Tail; } else { zcharacters = null; } break; } zsciiText = zsciiText.Add(this.GetZsciiAlphabetCharacter((byte)((currentAlphabet * 26) + zcharacter - 6))); break; } }