public override int Deserialize(System.Byte[] serialized, int startIndex) { int curIndex = startIndex; data = BitConverter.ToUInt16(serialized, curIndex); curIndex += BitConverter.GetBytes(data).Length; return (curIndex - startIndex); }
// Raise exception if nodeIndex is out of range private void VerifyNodeIndexInBounds(NodeIndex nodeIndex) { if (nodeIndex >= nodeCount) { throw new System.ArgumentOutOfRangeException("AdaptiveHuffmanTree NodeIndex of " + nodeIndex + " is out of range " + nodeCount); } }
private void InputChanged(UINT16 value) { value &= (UINT16)bitMask; bool newValue = false; if (bitCombine == BitCombine.AND) { if (value == bitMask) { newValue = true; } } else if (bitCombine == BitCombine.OR) { if (value != 0x00) { newValue = true; } } if (_value != newValue) { _value = newValue; if (OnWireInputChanged != null) { OnWireInputChanged(_value); } OnValueChanged.Invoke(_value); } }
public void RPC_JumpToMap(RPC.PackageWriter pkg, System.UInt16 mapid, System.Single x, System.Single z) { pkg.Write(mapid); pkg.Write(x); pkg.Write(z); pkg.SetMethod(4); }
// Tree restructuring routines // Perform tree update/restructure // This updates the count for the given code and restructures the tree if needed. // This is used after a tree search to update the tree (gives more frequently used // codes a shorter bit encoding). public void UpdateCodeCount(NodeData code) { VerifyNodeDataInBounds(code); // Get the index of the node containing this code NodeIndex curNodeIndex = parentIndex[code + nodeCount]; subtreeCount[curNodeIndex]++; // Update the node count // Propagate the count increase up to the root of the tree while (curNodeIndex != rootNodeIndex) { // Find the block leader of the block // Note: the block leader is the "rightmost" node with count equal to the // count of the current node, BEFORE the count of the current node is // updated. (The current node has already had it's count updated.) NodeIndex blockLeaderIndex = curNodeIndex; while (subtreeCount[curNodeIndex] > subtreeCount[blockLeaderIndex + 1]) { blockLeaderIndex++; } // Check if Current Node needs to be swapped with the Block Leader //if (curNodeIndex != blockLeaderIndex) { SwapNodes(curNodeIndex, blockLeaderIndex); curNodeIndex = blockLeaderIndex; // Update index of current node } // Follow the current node up to it's parent curNodeIndex = parentIndex[curNodeIndex]; // Increment the count of this new node subtreeCount[curNodeIndex]++; } }
}/* z_print_num */ /* * print_object * * Print an object description. * */ internal static void print_object(zword object_var) { zword addr = CObject.object_name(object_var); zword code = 0x94a5; zbyte length; FastMem.LOW_BYTE(addr, out length); addr++; if (length != 0) { FastMem.LOW_WORD(addr, out code); } if (code == 0x94a5) /* encoded text 0x94a5 == empty string */ { print_string("object#"); /* supply a generic name */ print_num(object_var); /* for anonymous objects */ } else { decode_text(string_type.LOW_STRING, addr); } }/* print_object */
}/* first_property */ /* * next_property * * Calculate the address of the next property in a property list. * */ static zword next_property(zword prop_addr) { zbyte value; /* Load the current property id */ FastMem.LOW_BYTE(prop_addr, out value); prop_addr++; /* Calculate the length of this property */ if (main.h_version <= ZMachine.V3) { value >>= 5; } else if (!((value & 0x80) > 0)) { value >>= 6; } else { FastMem.LOW_BYTE(prop_addr, out value); value &= 0x3f; if (value == 0) { value = 64; /* demanded by Spec 1.0 */ } } /* Add property length to current property pointer */ return((zword)(prop_addr + value + 1)); }/* next_property */
// Returns true if the node is a terminal node. // This is used to know when a tree search has completed. public bool IsLeaf(NodeIndex nodeIndex) { VerifyNodeIndexInBounds(nodeIndex); // Return whether or not this is a terminal node return(linkOrData[nodeIndex] >= nodeCount); }
}/* z_print_char */ /* * z_print_form, print a formatted table. * * zargs[0] = address of formatted table to be printed * */ internal static void z_print_form() { zword count; zword addr = Process.zargs[0]; bool first = true; for (;;) { FastMem.LOW_WORD(addr, out count); addr += 2; if (count == 0) { break; } if (!first) { Buffer.new_line(); } while (count-- > 0) { zbyte c; FastMem.LOW_BYTE(addr, out c); addr++; Buffer.print_char(translate_from_zscii(c)); } first = false; } }/* z_print_form */
}/* unicode_to_zscii */ /* * translate_to_zscii * * Map a Unicode character onto the ZSCII alphabet. * */ internal static zbyte translate_to_zscii(zword c) { if (c == CharCodes.ZC_SINGLE_CLICK) { return(0xfe); } if (c == CharCodes.ZC_DOUBLE_CLICK) { return(0xfd); } if (c == CharCodes.ZC_MENU_CLICK) { return(0xfc); } if (c == 0) { return(0); } c = unicode_to_zscii(c); if (c == 0) { c = '?'; } return((zbyte)c); }/* translate_to_zscii */
// Private function to swap two nodes in the Huffman tree. // This is used during tree restructing by UpdateCodeCount. private void SwapNodes(NodeIndex nodeIndex1, NodeIndex nodeIndex2) { // Swap Count values (subtreeCount[nodeIndex1], subtreeCount[nodeIndex2]) = (subtreeCount[nodeIndex2], subtreeCount[nodeIndex1]); // Update the Parent of the children // Note: If the current node is a terminal node (data node) then the left // child is a code value and it's "parent" must be updated but there is // no right child to update a parent link for. If the current node is not // a terminal node (not a data node) then both left and right child nodes // need to have their parent link updated NodeType temp = linkOrData[nodeIndex1]; parentIndex[temp] = nodeIndex2; // Update left child if (temp < nodeCount) // Check for non-data node (has right child) { parentIndex[temp + 1] = nodeIndex2; // Update right child } temp = linkOrData[nodeIndex2]; parentIndex[temp] = nodeIndex1; // Update left child if (temp < nodeCount) // Check for non-data node (has right child) { parentIndex[temp + 1] = nodeIndex1; // Update right child } // Swap Data values (link to children or code value) (linkOrData[nodeIndex1], linkOrData[nodeIndex2]) = (linkOrData[nodeIndex2], linkOrData[nodeIndex1]); }
}/* lookup_text */ /* * tokenise_text * * Translate a single word to a token and append it to the token * buffer. Every token consists of the address of the dictionary * entry, the length of the word and the offset of the word from * the start of the text buffer. Unknown words cause empty slots * if the flag is set (such that the text can be scanned several * times with different dictionaries); otherwise they are zero. * */ static void tokenise_text(zword text, zword length, zword from, zword parse, zword dct, bool flag) { zword addr; zbyte token_max, token_count; FastMem.LOW_BYTE(parse, out token_max); parse++; FastMem.LOW_BYTE(parse, out token_count); if (token_count < token_max) /* sufficient space left for token? */ { FastMem.storeb(parse++, (zbyte)(token_count + 1)); load_string((zword)(text + from), length); addr = lookup_text(0x05, dct); if (addr != 0 || !flag) { parse += (zword)(4 * token_count); // Will parse get updated properly? FastMem.storew((zword)(parse + 0), addr); FastMem.storeb((zword)(parse + 2), (zbyte)length); FastMem.storeb((zword)(parse + 3), (zbyte)from); } } }/* tokenise_text */
internal static zword unicode_tolower(zword c) { if (c < 0x0100) { c = tolower_basic_latin[c]; } else if (c == 0x0130) { c = 0x0069; /* Capital I with dot -> lower case i */ } else if (c == 0x0178) { c = 0x00FF; /* Capital Y diaeresis -> lower case y diaeresis */ } else if (c < 0x0180) { c = (zword)(tolower_latin_extended_a[c - 0x100] + 0x100); } else if (c >= 0x380 && c < 0x3D0) { c = (zword)(tolower_greek[c - 0x380] + 0x300); } else if (c >= 0x400 && c < 0x460) { c = (zword)(tolower_cyrillic[c - 0x400] + 0x400); } return(c); }
}/* script_word */ /* * script_write_input * * Send an input line to the transscript file. * */ internal static void script_write_input(zword[] buf, zword key) { int width; int i; for (i = 0, width = 0; buf[i] != 0; i++) { width++; } if (main.option_script_cols != 0 && script_width + width > main.option_script_cols) { script_new_line(); } for (i = 0; buf[i] != 0; i++) { script_char(buf[i]); } if (key == CharCodes.ZC_RETURN) { script_new_line(); } }/* script_write_input */
public void RegGateServer(RPC.PackageWriter pkg, System.String ip, System.UInt16 port, System.UInt64 id) { pkg.Write(ip); pkg.Write(port); pkg.Write(id); pkg.SetMethod(1); }
public void GetInfo([XmlElement("NewMaxCharsPassword", Namespace = "")] out ui2 MaxCharsPassword, [XmlElement("NewMinCharsPassword", Namespace = "")] out ui2 MinCharsPassword, [XmlElement("NewAllowedCharsPassword", Namespace = "")] out string AllowedCharsPassword) { object[] results = this.Invoke("GetInfo", new object[] { }); MaxCharsPassword = (ui2)results[0]; MinCharsPassword = (ui2)results[1]; AllowedCharsPassword = (string)results[2]; }
public void BNE命令を実行するとZeroフラグが立っているときだけプログラムカウンタに指定したアドレスが設定される(bool zeroFlag) { var statusFlagsPropertyInfo = sut.GetType().GetProperty("statusFlags", BindingFlags.NonPublic | BindingFlags.Instance); var statusFlags = statusFlagsPropertyInfo.GetValue(sut) as CPU.StatusFlags; statusFlags.Zero = zeroFlag; var registersPropertyInfo = sut.GetType().GetProperty("registers", BindingFlags.NonPublic | BindingFlags.Instance); var registers = registersPropertyInfo.GetValue(sut) as CPU.Registers; registers.PC = (Address)0x0000; const Address address = 0x8080; sut.AsDynamic().BNE(CPU.AddressingMode.Relative, address); if (zeroFlag) { registers.PC.Is((Address)0x0000); } else { registers.PC.Is(address); } }
}/* translate_to_zscii */ /* * alphabet * * Return a character from one of the three character sets. * */ static zword alphabet(int set, int index) { if (main.h_version > ZMachine.V1 && set == 2 && index == 1) { return(0x0D); /* always newline */ } if (main.h_alphabet != 0) /* game uses its own alphabet */ { zbyte c; zword addr = (zword)(main.h_alphabet + 26 * set + index); FastMem.LOW_BYTE(addr, out c); return(translate_from_zscii(c)); } else /* game uses default alphabet */ if (set == 0) { return((zword)('a' + index)); } else if (set == 1) { return((zword)('A' + index)); } else if (main.h_version == ZMachine.V1) { return(" 0123456789.,!?_#'\"/\\<-:()"[index]); } else { return(" ^0123456789.,!?_#'\"/\\-:()"[index]); } }/* alphabet */
}/* hot_key_quit */ /* * handle_hot_key * * Perform the action associated with a so-called hot key. Return * true to abort the current input action. * */ public static bool HandleHotkey(zword key) { if (Main.cwin == 0) { Text.PrintString("\nHot key -- "); bool aborting = key switch { CharCodes.ZC_HKEY_RECORD => HotkeyRecording(), CharCodes.ZC_HKEY_PLAYBACK => HotkeyPlayback(), CharCodes.ZC_HKEY_SEED => HitkeySeed(), CharCodes.ZC_HKEY_UNDO => HotkeyUndo(), CharCodes.ZC_HKEY_RESTART => HotkeyRestart(), CharCodes.ZC_HKEY_QUIT => HotkeyQuit(), CharCodes.ZC_HKEY_DEBUG => HotkeyDebugging(), CharCodes.ZC_HKEY_HELP => HotkeyHelp(), _ => false, }; if (aborting) { return(false); } Text.PrintString("\nContinue input...\n"); } return(false); }/* handle_hot_key */
}/* find_resolution */ /* * load_string * * Copy a ZSCII string from the memory to the global "decoded" string. * */ internal static void load_string(zword addr, zword length) { int i = 0; if (resolution == 0) { find_resolution(); } while (i < 3 * resolution) { if (i < length) { zbyte c; FastMem.LOW_BYTE(addr, out c); addr++; decoded[i++] = Text.translate_from_zscii(c); } else { decoded[i++] = 0; } } }/* load_string */
// Return a child node of the given node. // This is used to traverse the tree to a terminal node. // bRight = 1 --> follow right branch public NodeIndex GetChildNode(NodeIndex nodeIndex, bool bRight) { VerifyNodeIndexInBounds(nodeIndex); // Return the child node index return((NodeIndex)(linkOrData[nodeIndex] + (bRight ? 1 : 0))); }
// Raise exception if code is out of range private void VerifyNodeDataInBounds(NodeData code) { if (code >= terminalNodeCount) { throw new System.ArgumentOutOfRangeException("AdaptiveHuffmanTree NodeData of " + code + " is out of range " + terminalNodeCount); } }
/* * init_buffer * * Initialize buffer variables. * */ internal static void init_buffer() { buffer_var = new zword[General.TEXT_BUFFER_SIZE]; bufpos = 0; prev_c = 0; locked = false; }
//zword unicode_tolower (zword); /* * is_terminator * * Check if the given key is an input terminator. * */ internal static bool is_terminator(zword key) { if (key == CharCodes.ZC_TIME_OUT) return true; if (key == CharCodes.ZC_RETURN) return true; if (key >= CharCodes.ZC_HKEY_MIN && key <= CharCodes.ZC_HKEY_MAX) return true; if (main.h_terminating_keys != 0) if (key >= CharCodes.ZC_ARROW_MIN && key <= CharCodes.ZC_MENU_CLICK) { zword addr = main.h_terminating_keys; zbyte c; do { FastMem.LOW_BYTE(addr, out c); if (c == 255 || key == Text.translate_from_zscii (c)) return true; addr++; } while (c != 0); } return false; }/* is_terminator */
protected override void Execute(int execID, EntityID entity, ref ProjectileSpawnerComponent spawner, ref TransformComponent trans) { const int SHOTS_PER_BURST = 5; const float COOLDOWN_AFTER_BURST = 1.5f; const float COOLDOWN_BETWEEN_SHOTS = .05f; spawner.Cooldown -= deltaTime.Value; if (spawner.Cooldown > 0f) //Still cooling down so early out { return; } if (spawner.Target != null && context.HasEntity(spawner.Target.Value) && !context.HasTags(spawner.Target.Value, disabledMask)) { FireProjectile(ref spawner, ref trans); } spawner.Cooldown = COOLDOWN_BETWEEN_SHOTS; spawner.ShotsRemaining--; //If there are no shots-remaining then start cooling down if (spawner.ShotsRemaining <= 0) { spawner.ShotsRemaining = SHOTS_PER_BURST; spawner.Cooldown = COOLDOWN_AFTER_BURST; EntityID target; if (colliderManager.Intersect(AABox.FromCenterAndExtents(trans.Matrix.Position, new Vector3(75f, 125f, 75f)), out target)) { spawner.Target = target; } } }
static int FindYAbove(Level lvl, ushort x, ushort y, ushort z) { for (; y <= lvl.Height; y++) { BlockID above = lvl.GetBlock(x, (ushort)(y + 1), z); if (above == Block.Invalid) { continue; } if (!CollideType.IsSolid(lvl.CollideType(above))) { continue; } int posY = (y + 1) * 32 - 6; BlockDefinition def = lvl.GetBlockDef(above); if (def != null) { posY += def.MinZ * 2; } return(posY); } return(-1); }
public void RegLogServer(RPC.PackageWriter pkg, System.String ListenIp, System.UInt16 ListenPort, System.UInt64 id) { pkg.Write(ListenIp); pkg.Write(ListenPort); pkg.Write(id); pkg.SetMethod(6); }
public RecordStruct(Story story_id, zword release, string serial) { this.story_id = story_id; this.release = release; this.serial = serial; }
public override void Use(Player p, string message, CommandData data) { if (message.Length == 0) { Help(p); return; } if (!p.Supports(CpeExt.HeldBlock)) { p.Message("Your client doesn't support changing your held block."); return; } string[] args = message.SplitSpaces(2); BlockID block; if (!CommandParser.GetBlock(p, args[0], out block)) { return; } bool locked = false; if (args.Length > 1 && !CommandParser.GetBool(p, args[1], ref locked)) { return; } if (Block.IsPhysicsType(block)) { p.Message("Cannot hold physics blocks"); return; } BlockID raw = p.ConvertBlock(block); p.Send(Packet.HoldThis(raw, locked, p.hasExtBlocks)); p.Message("Set your held block to {0}.", Block.GetName(p, block)); }
protected override void Execute(int execID, EntityID entity, ref AgeComponent age, ref LifetimeComponent lifetime) { if (age.Value > lifetime.TotalLifetime) { context.RemoveEntity(entity); } }
}/* reset_memory */ /* * storeb * * Write a byte value to the dynamic Z-machine memory. * */ internal static void storeb(zword addr, zbyte value) { if (addr >= main.h_dynamic_size) { Err.runtime_error(ErrorCodes.ERR_STORE_RANGE); } if (addr == ZMachine.H_FLAGS + 1) { /* flags register is modified */ main.h_flags &= (zword)(~(ZMachine.SCRIPTING_FLAG | ZMachine.FIXED_FONT_FLAG)); main.h_flags |= (zword)(value & (ZMachine.SCRIPTING_FLAG | ZMachine.FIXED_FONT_FLAG)); if ((value & ZMachine.SCRIPTING_FLAG) > 0) { if (!main.ostream_script) { Files.script_open(); } } else { if (main.ostream_script) { Files.script_close(); } } Screen.refresh_text_style(); } SET_BYTE(addr, value); DebugState.Output("storeb: {0} -> {1}", addr, value); }/* storeb */
internal static void SET_WORD(long addr, zword v) { ZMData[addr] = HI(v); ZMData[addr + 1] = LO(v); DebugState.Output("ZMP: {0} -> {1}", addr, v); }
// texture_pixel_blending != 0 --> linear mag filter, otherwise nearest // texture_antialiasing_type != 0 --> linear min filter, otherwise linear mipmap linear /* * void LWTexture::processTexture(){ * ID4 chunk_type = f.read_ID4(); * U2 chunk_length = f.read_U2(); * * f.pushDomain( chunk_length ); * * switch( chunk_type ){ * case ID.TFLG: readTextureFlags_U2 (); break; * case ID.TSIZ: readTextureSize_VEC12 (); break; * case ID.TCTR: readTextureCenter_VEC12 (); break; * case ID.TFAL: readTextureFallOff_VEC12 (); break; * case ID.TVEL: readTextureVelocity_VEC12 (); break; * case ID.TREF: readTextureReferenceObject_S0(); break; * case ID.TCLR: readTextureColor_COL4 (); break; * case ID.TVAL: readTextureValue_IP2 (); break; * case ID.TAMP: readBumpTextureAmplitude_FP4 (); break; * case ID.TFP : readTextureAlgorithm_F4 (); break; // ns not yet handled * case ID.TIP : readTextureAlgorithm_I2 (); break; * case ID.TSP : readTextureAlgorithm_F4 (); break; // obsolete * case ID.TFRQ: readTextureAlgorithm_I2 (); break; // obsolete * case ID.TIMG: readImageMap_FNAM0 (); break; * case ID.TALP: readImageAlpha_FNAM0 (); break; * case ID.TWRP: readImageWarpOptions_U2_U2 (); break; * case ID.TAAS: readAntialiasingStrength_FP4 (); break; * case ID.TOPC: readTextureOpacity_FP4 (); break; * default: break; * } * * f.popDomain( true ); * * } */ public void readTextureFlags_U2() { #if false U2 flags = f.ReadU2(); if ((flags & LW_TF_AXIS_X) == LW_TF_AXIS_X) { texture_major_axis = TextureAxis.X; } if ((flags & LW_TF_AXIS_Y) == LW_TF_AXIS_Y) { texture_major_axis = TextureAxis.Y; } if ((flags & LW_TF_AXIS_Z) == LW_TF_AXIS_Z) { texture_major_axis = TextureAxis.Z; } //if( flags & LW_TF_WORLD_COORDINATES ){} //if( flags & LW_TF_NEGATIVE_IMAGE ){} if ((flags & LW_TF_PIXEL_BLENDING) == LW_TF_PIXEL_BLENDING) { texture_antialiasing_type = 1; } if ((flags & LW_TF_ANTIALISING) == LW_TF_ANTIALISING) { texture_pixel_blending = 1; } #endif }
/* * init_buffer * * Initialize buffer variables. * */ internal static void init_buffer() { buffer_var = new zword[General.TEXT_BUFFER_SIZE]; bufpos = 0; prev_c = 0; locked = false; }
public override int Deserialize(System.Byte[] serialized, int startIndex) { int curIndex = startIndex; status = (System.SByte)serialized[curIndex]; curIndex++; service = BitConverter.ToUInt16(serialized, curIndex); curIndex += BitConverter.GetBytes(service).Length; return (curIndex - startIndex); }
/* * start_sample * * Call the IO interface to play a sample. * */ static void start_sample(int number, int volume, int repeats, zword eos) { if (main.story_id == Story.LURKING_HORROR) repeats = lh_repeats[number]; os_.start_sample(number, volume, repeats, eos); playing = true; }/* start_sample */
public Word this[Word address] { get { return ram[address]; } set { ram[address] = value; } }
public int index; // szurgot public zword this[int index] { get { switch (index) { case 0: return y_pos; case 1: return x_pos; case 2: return y_size; case 3: return x_size; case 4: return y_cursor; case 5: return x_cursor; case 6: return left; case 7: return right; case 8: return nl_routine; case 9: return nl_countdown; case 10: return style; case 11: return colour; case 12: return font; case 13: return font_size; case 14: return attribute; case 15: return line_count; case 16: return true_fore; case 17: return true_back; } return 0; } set { switch (index) { case 0: y_pos = value; break; case 1: x_pos = value; break; case 2: y_size = value; break; case 3: x_size = value; break; case 4: y_cursor = value; break; case 5: x_cursor = value; break; case 6: left = value; break; case 7: right = value; break; case 8: nl_routine = value; break; case 9: nl_countdown = value; break; case 10: style = value; break; case 11: colour = value; break; case 12: font = value; break; case 13: font_size = value; break; case 14: attribute = value; break; case 15: line_count = value; break; case 16: true_fore = value; break; case 17: true_back = value; break; } } }
public nsFont(string name, uint8_t style, uint8_t systemFont, uint8_t variant, uint8_t decorations, uint16_t weight, int16_t stretch, nscoord size, float sizeAdjust = 0, string languageOverride = null) { this.name = name; this.style = style; this.systemFont = systemFont; this.variant = variant; this.decorations = decorations; this.weight = weight; this.stretch = stretch; this.size = size; this.sizeAdjust = sizeAdjust; this.languageOverride = languageOverride; }
public MyElement() { m_Matrix = Matrix.Identity; m_CollisionLayer = 0; Flags = MyElementFlag.EF_AABB_DIRTY; m_AABB = new BoundingBox(); m_ProxyData = PROXY_UNASSIGNED; m_ShadowProxyData = PROXY_UNASSIGNED; m_Guid = GUID_COUNTER; if (GUID_COUNTER == int.MaxValue) { GUID_COUNTER = 0; } GUID_COUNTER++; }
}/* object_address */ /* * object_name * * Return the address of the given object's name. * */ internal static zword object_name(zword object_var) { zword obj_addr; zword name_addr; obj_addr = object_address(object_var); /* The object name address is found at the start of the properties */ if (main.h_version <= ZMachine.V3) obj_addr += O1_PROPERTY_OFFSET; else obj_addr += O4_PROPERTY_OFFSET; FastMem.LOW_WORD(obj_addr, out name_addr); return name_addr; }/* object_name */
/* * object_address * * Calculate the address of an object. * */ internal static zword object_address(zword obj) { /* Check object number */ if (obj > ((main.h_version <= ZMachine.V3) ? 255 : MAX_OBJECT)) { Text.print_string("@Attempt to address illegal object "); Text.print_num(obj); Text.print_string(". This is normally fatal."); Buffer.new_line(); Err.runtime_error(ErrorCodes.ERR_ILL_OBJ); } /* Return object address */ if (main.h_version <= ZMachine.V3) return (zword)(main.h_objects + ((obj - 1) * O1_SIZE + 62)); else return (zword)(main.h_objects + ((obj - 1) * O4_SIZE + 126)); }/* object_address */
///* // * flush_buffer // * // * Copy the contents of the text buffer to the output streams. // * // */ internal static void flush_buffer () { /* Make sure we stop when flush_buffer is called from flush_buffer. Note that this is difficult to avoid as we might print a newline during flush_buffer, which might cause a newline interrupt, that might execute any arbitrary opcode, which might flush the buffer. */ if (locked || bufpos == 0) return; /* Send the buffer to the output streams */ buffer_var[bufpos] = '\0'; locked = true; Stream.stream_word (buffer_var); locked = false; /* Reset the buffer */ bufpos = 0; prev_c = 0; }/* flush_buffer */
}/* get_header_extension */ /* * set_header_extension * * Set an entry in the header extension (former mouse table). * */ internal static void set_header_extension(int entry, zword val) { zword addr; if (main.h_extension_table == 0 || entry > main.hx_table_size) return; addr = (zword)(main.h_extension_table + 2 * entry); SET_WORD(addr, val); }/* set_header_extension */
}/* erase_window */ /* * split_window * * Divide the screen into upper (1) and lower (0) windows. In V3 the upper * window appears below the status line. * */ internal static void split_window(zword height) { zword stat_height = 0; Buffer.flush_buffer(); /* Calculate height of status line and upper window */ if (main.h_version != ZMachine.V6) height *= FastMem.HI(wp[1].font_size); if (main.h_version <= ZMachine.V3) { stat_height = FastMem.HI(wp[7].font_size); wp[7].y_size = stat_height; os_.set_window_size(7, wp[7]); } else { wp[7].y_size = 0; } /* Cursor of upper window mustn't be swallowed by the lower window */ wp[1].y_cursor += (zword)(wp[1].y_pos - 1 - stat_height); wp[1].y_pos = (zword)(1 + stat_height); wp[1].y_size = height; if ((short)wp[1].y_cursor > (short)wp[1].y_size) reset_cursor(1); /* Cursor of lower window mustn't be swallowed by the upper window */ wp[0].y_cursor += (zword)(wp[0].y_pos - 1 - stat_height - height); wp[0].y_pos = (zword)(1 + stat_height + height); wp[0].y_size = (zword)(main.h_screen_height - stat_height - height); if ((short)wp[0].y_cursor < 1) reset_cursor(0); /* Erase the upper window in V3 only */ if (main.h_version == ZMachine.V3 && height != 0) erase_window(1); os_.set_window_size(0, wp[0]); os_.set_window_size(1, wp[1]); }/* split_window */
}/* split_window */ /* * erase_screen * * Erase the entire screen to background colour. * */ static void erase_screen(zword win) { int i; if (FastMem.HI(cwp.colour) != ZColor.TRANSPARENT_COLOUR) os_.erase_area(1, 1, main.h_screen_height, main.h_screen_width, -2); if (win == zword.MaxValue) { split_window(0); set_window(0); reset_cursor(0); } for (i = 0; i < 8; i++) wp[i].line_count = 0; }/* erase_screen */
public GdkColor (Color value) { pixel = 0; red = (guint16)(value.R << 8); green = (guint16)(value.G << 8); blue = (guint16)(value.B << 8); }
}/* z_restore */ /* * mem_diff * * Set diff to a Quetzal-like difference between a and b, * copying a to b as we go. It is assumed that diff points to a * buffer which is large enough to hold the diff. * mem_size is the number of bytes to compare. * Returns the number of bytes copied to diff. * */ static long mem_diff(zbyte[] a, zbyte[] b, zword mem_size, zbyte[] diff) { zword size = mem_size; int dPtr = 0; uint j; zbyte c = 0; int aPtr = 0; int bPtr = 0; for (; ; ) { for (j = 0; size > 0 && (c = (zbyte)(a[aPtr++] ^ b[bPtr++])) == 0; j++) size--; if (size == 0) break; size--; if (j > 0x8000) { diff[dPtr++] = 0; diff[dPtr++] = 0xff; diff[dPtr++] = 0xff; j -= 0x8000; } if (j > 0) { diff[dPtr++] = 0; j--; if (j <= 0x7f) { diff[dPtr++] = (byte)j; } else { diff[dPtr++] = (byte)((j & 0x7f) | 0x80); diff[dPtr++] = (byte)((j & 0x7f80) >> 7); } } diff[dPtr++] = c; b[bPtr - 1] ^= c; } return dPtr; }/* mem_diff */
}/* z_restart */ /* * get_default_name * * Read a default file name from the memory of the Z-machine and * copy it to a string. * */ internal static string get_default_name(zword addr) { if (addr != 0) { var sb = new System.Text.StringBuilder(); zbyte len; int i; FastMem.LOW_BYTE(addr, out len); addr++; for (i = 0; i < len; i++) { zbyte c; FastMem.LOW_BYTE(addr, out c); addr++; if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; // default_name[i] = c; sb.Append((char)c); } // default_name[i] = 0; if (sb.ToString().IndexOf(".") == -1) { sb.Append(".AUX"); return sb.ToString(); } else return auxilary_name; } return null; }/* get_default_name */
}/* storeb */ /* * storew * * Write a word value to the dynamic Z-machine memory. * */ internal static void storew(zword addr, zword value) { storeb((zword)(addr + 0), HI(value)); storeb((zword)(addr + 1), LO(value)); }/* storew */
}/* reset_memory */ /* * storeb * * Write a byte value to the dynamic Z-machine memory. * */ internal static void storeb(zword addr, zbyte value) { if (addr >= main.h_dynamic_size) Err.runtime_error(ErrorCodes.ERR_STORE_RANGE); if (addr == ZMachine.H_FLAGS + 1) { /* flags register is modified */ main.h_flags &= (zword)(~(ZMachine.SCRIPTING_FLAG | ZMachine.FIXED_FONT_FLAG)); main.h_flags |= (zword)(value & (ZMachine.SCRIPTING_FLAG | ZMachine.FIXED_FONT_FLAG)); if ((value & ZMachine.SCRIPTING_FLAG) > 0) { if (!main.ostream_script) Files.script_open(); } else { if (main.ostream_script) Files.script_close(); } Screen.refresh_text_style(); } SET_BYTE(addr, value); DebugState.Output("storeb: {0} -> {1}", addr, value); }/* storeb */
internal static byte LO(zword v) { return (byte)(v & 0xff); }
}/* set_window */ /* * erase_window * * Erase a window to background colour. * */ internal static void erase_window(zword win) { zword y = wp[win].y_pos; zword x = wp[win].x_pos; if (main.h_version == ZMachine.V6 && win != main.cwin && !Screen.amiga_screen_model()) os_.set_colour(FastMem.LO(wp[win].colour), FastMem.HI(wp[win].colour)); if (FastMem.HI(wp[win].colour) != ZColor.TRANSPARENT_COLOUR) { os_.erase_area(y, x, y + wp[win].y_size - 1, x + wp[win].x_size - 1, win); } if (main.h_version == ZMachine.V6 && win != main.cwin && !amiga_screen_model()) os_.set_colour(FastMem.LO(cwp.colour), FastMem.HI(cwp.colour)); reset_cursor(win); wp[win].line_count = 0; }/* erase_window */
internal static void CODE_WORD(out zword v) { v = (zword)(ZMData[pcp] << 8 | ZMData[pcp + 1]); pcp += 2; }
// TODO I'm suprised that they return the same thing internal static void HIGH_WORD(long addr, out zword v) { LOW_WORD(addr, out v); }
internal static void LOW_WORD(long addr, out zword v) { v = (ushort)((ZMData[addr] << 8) | ZMData[addr + 1]); }
internal static void SET_WORD(long addr, zword v) { ZMData[addr] = HI(v); ZMData[addr + 1] = LO(v); DebugState.Output("ZMP: {0} -> {1}", addr, v); }
internal static byte HI(zword v) { return (byte)(v >> 8); }
}/* restart_header */ /* * init_memory * * Allocate memory and load the story file. * */ internal static void init_memory() { long size; zword addr; zword n; int i, j; // TODO Abstract this part /* Open story file */ // story_fp = new System.IO.FileStream(main.story_name, System.IO.FileMode.Open, System.IO.FileAccess.Read); story_fp = os_.path_open(main.story_data); if (story_fp == null) { os_.fatal("Cannot open story file"); } init_fp_pos = story_fp.Position; storyData = new byte[story_fp.Length]; story_fp.Read(storyData, 0, storyData.Length); story_fp.Position = 0; DebugState.Output("Starting story: {0}", main.story_name); /* Allocate memory for story header */ ZMData = new byte[64]; Frotz.Other.ZMath.clearArray(ZMData); /* Load header into memory */ if (story_fp.Read(ZMData, 0, 64) != 64) { os_.fatal("Story file read error"); } /* Copy header fields to global variables */ LOW_BYTE(ZMachine.H_VERSION, out main.h_version); if (main.h_version < ZMachine.V1 || main.h_version > ZMachine.V8) { os_.fatal("Unknown Z-code version"); } LOW_BYTE(ZMachine.H_CONFIG, out main.h_config); if (main.h_version == ZMachine.V3 && ((main.h_config & ZMachine.CONFIG_BYTE_SWAPPED) != 0)) { os_.fatal("Byte swapped story file"); } LOW_WORD(ZMachine.H_RELEASE, out main.h_release); LOW_WORD(ZMachine.H_RESIDENT_SIZE, out main.h_resident_size); LOW_WORD(ZMachine.H_START_PC, out main.h_start_pc); LOW_WORD(ZMachine.H_DICTIONARY, out main.h_dictionary); LOW_WORD(ZMachine.H_OBJECTS, out main.h_objects); LOW_WORD(ZMachine.H_GLOBALS, out main.h_globals); LOW_WORD(ZMachine.H_DYNAMIC_SIZE, out main.h_dynamic_size); LOW_WORD(ZMachine.H_FLAGS, out main.h_flags); for (i = 0, addr = ZMachine.H_SERIAL; i < 6; i++, addr++) { LOW_BYTE(addr, out main.h_serial[i]); } // TODO serial might need to be a char /* Auto-detect buggy story files that need special fixes */ main.story_id = Story.UNKNOWN; for (i = 0; records[i].story_id != Story.UNKNOWN; i++) { if (main.h_release == records[i].release) { for (j = 0; j < 6; j++) if (main.h_serial[j] != records[i].serial[j]) goto no_match; main.story_id = records[i].story_id; } no_match: ; /* null statement */ } LOW_WORD(ZMachine.H_ABBREVIATIONS, out main.h_abbreviations); LOW_WORD(ZMachine.H_FILE_SIZE, out main.h_file_size); /* Calculate story file size in bytes */ if (main.h_file_size != 0) { main.story_size = 2 * main.h_file_size; if (main.h_version >= ZMachine.V4) { main.story_size *= 2; } if (main.h_version >= ZMachine.V6) { main.story_size *= 2; } if (main.story_id == Story.AMFV && main.h_release == 47) { main.story_size = 2 * main.h_file_size; } else if (main.story_size > 0) {/* os_path_open() set the size */ } else {/* some old games lack the file size entry */ main.story_size = story_fp.Length - init_fp_pos; story_fp.Position = init_fp_pos + 64; } LOW_WORD(ZMachine.H_CHECKSUM, out main.h_checksum); LOW_WORD(ZMachine.H_ALPHABET, out main.h_alphabet); LOW_WORD(ZMachine.H_FUNCTIONS_OFFSET, out main.h_functions_offset); LOW_WORD(ZMachine.H_STRINGS_OFFSET, out main.h_strings_offset); LOW_WORD(ZMachine.H_TERMINATING_KEYS, out main.h_terminating_keys); LOW_WORD(ZMachine.H_EXTENSION_TABLE, out main.h_extension_table); /* Zork Zero beta and Macintosh versions don't have the graphics flag set */ if (main.story_id == Story.ZORK_ZERO) { if (main.h_release == 96 || main.h_release == 153 || main.h_release == 242 || main.h_release == 296) { main.h_flags |= ZMachine.GRAPHICS_FLAG; } } /* Adjust opcode tables */ if (main.h_version <= ZMachine.V4) { Process.op0_opcodes[0x09] = new Process.zinstruction(Variable.z_pop); Process.op0_opcodes[0x0f] = new Process.zinstruction(Math.z_not); } else { Process.op0_opcodes[0x09] = new Process.zinstruction(Process.z_catch); Process.op0_opcodes[0x0f] = new Process.zinstruction(Process.z_call_n); } /* Allocate memory for story data */ byte[] temp = new byte[ZMData.Length]; Frotz.Other.ZMath.clearArray(temp); System.Array.Copy(ZMData, temp, ZMData.Length); ZMData = new byte[main.story_size]; Frotz.Other.ZMath.clearArray(ZMData); System.Array.Copy(temp, ZMData, temp.Length); /* Load story file in chunks of 32KB */ n = 0x8000; for (size = 64; size < main.story_size; size += n) { if (main.story_size - size < 0x8000) n = (ushort)(main.story_size - size); SET_PC(size); int read = story_fp.Read(ZMData, (int)pcp, n); if (read != n) os_.fatal("Story file read error"); } // Take a moment to calculate the checksum of the story file in case verify is called ZMData_checksum = 0; for (int k = 64; k < ZMData.Length; k++) { ZMData_checksum += ZMData[k]; } } DebugState.Output("Story Size: {0}", main.story_size); first_restart = true; /* Read header extension table */ main.hx_table_size = get_header_extension(ZMachine.HX_TABLE_SIZE); main.hx_unicode_table = get_header_extension(ZMachine.HX_UNICODE_TABLE); main.hx_flags = get_header_extension(ZMachine.HX_FLAGS); }/* init_memory */
}/* refresh_text_style */ /* * set_window * * Set the current window. In V6 every window has its own set of window * properties such as colours, text style, cursor position and size. * */ static void set_window(zword win) { Buffer.flush_buffer(); main.cwin = win; cwp = wp[win]; update_attributes(); if (main.h_version == ZMachine.V6) { os_.set_colour(FastMem.LO(cwp.colour), FastMem.HI(cwp.colour)); if (os_.font_data(cwp.font, ref font_height, ref font_width)) os_.set_font(cwp.font); os_.set_text_style(cwp.style); } else refresh_text_style(); if (main.h_version != ZMachine.V6 && win != 0) { wp[win].y_cursor = 1; wp[win].x_cursor = 1; } update_cursor(); os_.set_active_window(win); }/* set_window */