示例#1
0
        public AdLibChannel(IOpl opl, byte[] musicData, ushort startOfData)
        {
            _opl = opl;
            _musicData = musicData;
            _channelData.loopPoint = startOfData;
            _channelData.eventDataPtr = startOfData;
            _channelData.channelActive = true;
            _channelData.tremoVibro = 0;
            _channelData.assignedInstrument = 0xFF;
            _channelData.channelVolume = 0x7F;
            _channelData.nextEventTime = GetNextEventTime();

            _channelData.adlibChannelNumber = _channelData.lastCommand = _channelData.note =
            _channelData.adlibReg1 = _channelData.adlibReg2 = _channelData.freqOffset = 0;
            _channelData.frequency = 0;
            _channelData.instrumentData = null;

            ushort instrumentDataLoc;

            if (SystemVars.Instance.GameVersion.Version.Minor == 109)
            {
                //instrumentDataLoc = (_musicData[0x11D0] << 8) | _musicData[0x11CF];
                //_frequenceTable = (uint16 *)(_musicData + 0x835);
                //_registerTable = _musicData + 0xE35;
                //_opOutputTable = _musicData + 0xE47;
                //_adlibRegMirror = _musicData + 0xF4A;

                instrumentDataLoc = _musicData.ToUInt16(0x1204);
                _frequenceTable = new UShortAccess(_musicData, 0x868);
                _registerTable = new ByteAccess(_musicData, 0xE68);
                _opOutputTable = new ByteAccess(_musicData, 0xE7A);
                _adlibRegMirror = new ByteAccess(_musicData, 0xF7D);
            }
            else if (SystemVars.Instance.GameVersion.Version.Minor == 267)
            {
                instrumentDataLoc = _musicData.ToUInt16(0x11FB);
                _frequenceTable = new UShortAccess(_musicData, 0x7F4);
                _registerTable = new ByteAccess(_musicData, 0xDF4);
                _opOutputTable = new ByteAccess(_musicData, 0xE06);
                _adlibRegMirror = new ByteAccess(_musicData, 0xF55);
            }
            else
            {
                instrumentDataLoc = _musicData.ToUInt16(0x1205);
                _frequenceTable = new UShortAccess(_musicData, 0x7FE);
                _registerTable = new ByteAccess(_musicData, 0xDFE);
                _opOutputTable = new ByteAccess(_musicData, 0xE10);
                _adlibRegMirror = new ByteAccess(_musicData, 0xF5F);
            }

            _instrumentMap = new ByteAccess(_musicData, instrumentDataLoc);
            _instruments = new StructAccess<InstrumentStruct>(_musicData, instrumentDataLoc + 0x80);
        }
示例#2
0
文件: GmMusic.cs 项目: scemino/nscumm
 protected override void SetupPointers()
 {
     if (SystemVars.Instance.GameVersion.Version.Minor == 109)
     {
         _musicDataLoc = _musicData.ToUInt16(0x79B);
         _sysExSequence = new ByteAccess(_musicData, 0x1EF2);
     }
     else
     {
         _musicDataLoc = _musicData.ToUInt16(0x7DC);
         _sysExSequence = new ByteAccess(_musicData, _musicData.ToUInt16(0x7E0));
     }
 }
        /// <summary>
        /// Send packets over the opened socket (internal function only, no error checking, locking, etc. mechanism is implemented)
        /// Only CRC is calculated before sending packet
        /// </summary>
        /// <param name="in_endpoint"></param>
        /// <param name="in_packet"></param>
        private void InternalPacketSend(EndPoint in_endpoint, byte[] in_packet)
        {
            // copy packet to the buffer
            in_packet.CopyTo(m_transmit_buffer, 0);

            // calculate and store CRC
            UInt16 crc;

            crc = CRC16.CalculateForBlock(CRC16.InitValue, in_packet, in_packet.Length);

            m_transmit_buffer[in_packet.Length]     = ByteAccess.LowByte(crc);
            m_transmit_buffer[in_packet.Length + 1] = ByteAccess.HighByte(crc);

            // send packet
            m_client.BeginSendTo(m_transmit_buffer, 0, in_packet.Length + PacketConstants.PacketCRCLength, 0, in_endpoint, new AsyncCallback(SendCallback), this);
        }
示例#4
0
文件: Text.cs 项目: scemino/nscumm
        public uint LowTextManager(ByteAccess ascii, int width, byte pen)
        {
            _textCount++;
            if (_textCount > MaxTextObs)
                throw new InvalidOperationException("Text::lowTextManager: MAX_TEXT_OBS exceeded");
            uint textObjId = ObjectMan.TEXT_sect * ObjectMan.ITM_PER_SEC - 1;
            do
            {
                textObjId++;
            } while (_objMan.FetchObject(textObjId).status != 0);
            // okay, found a free text object

            _objMan.FetchObject(textObjId).status = Logic.STAT_FORE;
            MakeTextSprite((byte)textObjId, ascii, (ushort)width, pen);

            return textObjId;
        }
示例#5
0
        public void Initialize()
        {
            ushort cnt;
            for (cnt = 0; cnt < TOTAL_SECTIONS; cnt++)
                _liveList[cnt] = 0; // we don't need to close the files here. When this routine is
                                    // called, the memory was flushed() anyways, so these resources
                                    // already *are* closed.

            _liveList[128] = _liveList[129] = _liveList[130] = _liveList[131] = _liveList[133] =
                                                  _liveList[134] = _liveList[145] = _liveList[146] = _liveList[TEXT_sect] = 1;

            for (cnt = 0; cnt < TOTAL_SECTIONS; cnt++)
            {
                if (_liveList[cnt] != 0)
                    _cptData[cnt] = new ByteAccess(_resMan.CptResOpen(_objectList[cnt]), Header.Size);
                else
                    _cptData[cnt] = null;
            }
        }
        /// <summary>
        /// Serializes packet header and pushes header and packet data into the queue with CRC calculation
        /// </summary>
        /// <param name="in_interface"></param>
        /// <param name="in_packet_header"></param>
        /// <param name="in_packet_data"></param>
        /// <returns></returns>
        public bool Push(byte in_interface, object in_packet_header, byte[] in_packet_data)
        {
            int    packet_index;
            UInt16 crc;

            // reserve storage for packet
            packet_index = ReservePushBuffer();
            if (packet_index == InvalidPacketIndex)
            {
                return(false);
            }

            // calculate packet size
            int raw_packet_size = Marshal.SizeOf(in_packet_header) + in_packet_data.Length;

            // serialize packet header
            byte[]   raw_packet_buffer = m_packets[packet_index].Buffer;
            GCHandle handle            = GCHandle.Alloc(raw_packet_buffer, GCHandleType.Pinned);
            IntPtr   buffer            = handle.AddrOfPinnedObject();

            Marshal.StructureToPtr(in_packet_header, buffer, false);
            handle.Free();

            // copy packet data
            in_packet_data.CopyTo(raw_packet_buffer, Marshal.SizeOf(in_packet_header));

            // update CRC
            crc = CRC16.CalculateForBlock(CRC16.InitValue, raw_packet_buffer, raw_packet_size);
            raw_packet_buffer[raw_packet_size + 0] = ByteAccess.LowByte(crc);
            raw_packet_buffer[raw_packet_size + 1] = ByteAccess.HighByte(crc);

            // change buffer state
            m_packets[packet_index].Interface = in_interface;
            m_packets[packet_index].Length    = (byte)(raw_packet_size + PacketConstants.PacketCRCLength);
            m_packets[packet_index].Timestamp = DateTime.Now;
            m_packets[packet_index].State     = PacketBufferState.Valid;

            return(true);
        }
示例#7
0
 public ControlButton(ushort x, ushort y, uint resId, ButtonIds id, byte flag, ResMan pResMan, byte[] screenBuf,
     ISystem system)
 {
     _x = x;
     _y = y;
     _id = id;
     _flag = flag;
     _resId = resId;
     _resMan = pResMan;
     _frameIdx = 0;
     _resMan.ResOpen(_resId);
     FrameHeader tmp = new FrameHeader(_resMan.FetchFrame(_resMan.FetchRes(_resId), 0));
     _width = _resMan.ReadUInt16(tmp.width);
     _width = (ushort)((_width > Screen.SCREEN_WIDTH) ? Screen.SCREEN_WIDTH : _width);
     _height = _resMan.ReadUInt16(tmp.height);
     if ((x == 0) && (y == 0))
     { // center the frame (used for panels);
         _x = (ushort)((((640 - _width) / 2) < 0) ? 0 : ((640 - _width) / 2));
         _y = (ushort)((((480 - _height) / 2) < 0) ? 0 : ((480 - _height) / 2));
     }
     _dstBuf = new ByteAccess(screenBuf, _y * Screen.SCREEN_WIDTH + _x);
     _system = system;
 }
示例#8
0
        protected override void SetupPointers()
        {
            if (SystemVars.Instance.GameVersion.Version.Minor == 109)
            {
                // disk demo uses a different AdLib driver version, some offsets have changed
                //_musicDataLoc = (_musicData[0x11CC] << 8) | _musicData[0x11CB];
                //_initSequence = _musicData + 0xEC8;

                _musicDataLoc = _musicData.ToUInt16(0x1200);
                _initSequence = new ByteAccess(_musicData, 0xEFB);
            }
            else if (SystemVars.Instance.GameVersion.Version.Minor == 267)
            {
                _musicDataLoc = _musicData.ToUInt16(0x11F7);
                _initSequence = new ByteAccess(_musicData, 0xE87);
            }
            else
            {
                _musicDataLoc = _musicData.ToUInt16(0x1201);
                _initSequence = new ByteAccess(_musicData, 0xE91);
            }
            _nextMusicPoll = 0;
        }
示例#9
0
        private bool ProcessPatchSysEx(ByteAccess sysExData)
        {
            byte[] sysExBuf = new byte[15];
            byte   crc      = 0;

            if ((sysExData[0] & 0x80) != 0)
            {
                return(false);
            }

            // decompress data from stream
            sysExBuf[0]  = 0x41;
            sysExBuf[1]  = 0x10;
            sysExBuf[2]  = 0x16;
            sysExBuf[3]  = 0x12;
            sysExBuf[4]  = 0x5;
            sysExBuf[5]  = (byte)(sysExData[0] >> 4);           // patch offset part 1
            sysExBuf[6]  = (byte)((sysExData[0] & 0xF) << 3);   // patch offset part 2
            sysExBuf[7]  = (byte)(sysExData[1] >> 6);           // timbre group
            sysExBuf[8]  = (byte)(sysExData[1] & 0x3F);         // timbre num
            sysExBuf[9]  = (byte)(sysExData[2] & 0x3F);         // key shift
            sysExBuf[10] = (byte)(sysExData[3] & 0x7F);         // fine tune
            sysExBuf[11] = (byte)(sysExData[4] & 0x7F);         // bender range
            sysExBuf[12] = (byte)(sysExData[2] >> 6);           // assign mode
            sysExBuf[13] = (byte)(sysExData[3] >> 7);           // reverb switch
            for (byte cnt = 4; cnt < 14; cnt++)
            {
                crc -= sysExBuf[cnt];
            }
            sysExBuf[14] = (byte)(crc & 0x7F);                  // crc
            _midiDrv.SysEx(sysExBuf, 15);
            // We delay the time it takes to send the sysEx plus an
            // additional 40ms, which is required for MT-32 rev00,
            // to assure no buffer overflow or missing bytes
            ServiceLocator.Platform.Sleep(17 * 1000 / 3125 + 40);
            return(true);
        }
示例#10
0
文件: Text.cs 项目: scemino/nscumm
        private ushort AnalyzeSentence(ByteAccess textSrc, ushort maxWidth, LineInfo[] line)
        {
            ushort lineNo = 0;
            var text = new ByteAccess(textSrc.Data, textSrc.Offset);
            var firstWord = true;
            while (text.Offset < text.Data.Length && text[0] != 0)
            {
                ushort wordWidth = 0;
                ushort wordLength = 0;

                while (text.Offset < text.Data.Length && (text[0] != ' ') && text[0] != 0)
                {
                    wordWidth = (ushort)(wordWidth + CharWidth(text[0]) - Overlap);
                    wordLength++;
                    text.Offset++;
                }
                if (text.Offset < text.Data.Length && text[0] == ' ')
                    text.Offset++;

                wordWidth += Overlap; // no overlap on final letter of word!
                if (firstWord)
                { // first word on first line, so no separating SPACE needed
                    line[0].Width = wordWidth;
                    line[0].Length = wordLength;
                    firstWord = false;
                }
                else
                {
                    // see how much extra space this word will need to fit on current line
                    // (with a separating space character - also overlapped)
                    var spaceNeeded = (ushort)(_joinWidth + wordWidth);

                    if (line[lineNo].Width + spaceNeeded <= maxWidth)
                    {
                        line[lineNo].Width += spaceNeeded;
                        line[lineNo].Length = (ushort)(line[lineNo].Length + 1 + wordLength); // NB. space+word characters
                    }
                    else
                    {    // put word (without separating SPACE) at start of next line
                        lineNo++;
                        Debug.Assert(lineNo < MaxLines);
                        line[lineNo].Width = wordWidth;
                        line[lineNo].Length = wordLength;
                    }
                }
            }
            return (ushort)(lineNo + 1);  // return no of lines
        }
示例#11
0
文件: Text.cs 项目: scemino/nscumm
        private ushort CopyChar(byte ch, ByteAccess sprPtr, ushort sprWidth, byte pen)
        {
            if (ch < ' ')
                ch = 64;
            var chFrame = new FrameHeader(_resMan.FetchFrame(_font, (uint)(ch - ' ')));
            var chData = FrameHeader.Size;
            var dest = sprPtr;
            ByteAccess decChr;
            ushort frameHeight;

            if (SystemVars.Platform == Platform.PSX)
            {
                frameHeight = (ushort)(_resMan.ReadUInt16(chFrame.height) / 2);
                if (_fontId == SwordRes.CZECH_GAME_FONT)
                { //Czech game fonts are compressed
                    var decBuf = new byte[_resMan.ReadUInt16(chFrame.width) * (_resMan.ReadUInt16(chFrame.height) / 2)];
                    Screen.DecompressHIF(chFrame.Data.Data, chFrame.Data.Offset + chData, decBuf);
                    decChr = new ByteAccess(decBuf);
                }
                else //Normal game fonts are not compressed
                    decChr = new ByteAccess(chFrame.Data.Data, chFrame.Data.Offset + chData);
            }
            else
            {
                frameHeight = _resMan.ReadUInt16(chFrame.height);
                decChr = new ByteAccess(chFrame.Data.Data, chFrame.Data.Offset + chData);
            }

            for (ushort cnty = 0; cnty < frameHeight; cnty++)
            {
                for (ushort cntx = 0; cntx < _resMan.ReadUInt16(chFrame.width); cntx++)
                {
                    if (decChr[0] == LetterCol)
                        dest[cntx] = pen;
                    else if (((decChr[0] == BorderCol) || (decChr[0] == BorderColPsx)) && (dest[cntx] == 0)) // don't do a border if there's already a color underneath (chars can overlap)
                        dest[cntx] = BorderCol;
                    decChr.Offset++;
                }
                dest.Offset += sprWidth;
            }

            return _resMan.ReadUInt16(chFrame.width);
        }
示例#12
0
        /// <summary>
        /// Main thread function
        /// </summary>
        public void Run()
        {
            bool   event_occured;
            UInt16 crc;
            int    received_data_pos;
            int    received_packet_pos;

            // init SLIPs
            m_receiver_slip.ResetDecoder();

            try
            {
                m_serial_port                = new SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One);
                m_serial_port.ReadTimeout    = 50;
                m_serial_port.WriteTimeout   = 50;
                m_serial_port.ReadBufferSize = 4096;
                m_serial_port.Open();
            }
            catch
            {
                return;
            }

            // init
            m_upstream_bytes    = 0;
            m_downstream_bytes  = 0;
            received_data_pos   = 0;
            received_packet_pos = 0;

            // start data reception
            m_read_pending = true;
            m_serial_port.BaseStream.BeginRead(m_receive_data_buffer, 0, m_receive_data_buffer.Length, m_receiver_callback, this);

            // communication loop
            while (!m_stop_requested)
            {
                // wait for event
                event_occured = m_thread_event.WaitOne(ThreadWaitTimeout);

                // exit loop if thread must be stopped
                if (m_stop_requested)
                {
                    break;
                }

                // process received data
                if (m_received_data_length > 0)
                {
                    received_data_pos = 0;
                    while (received_data_pos < m_received_data_length)
                    {
                        // SLIP decode data
                        if (m_receiver_slip.DecodeBlock(m_receive_data_buffer, ref received_data_pos, m_received_data_length, m_receive_packet_buffer, ref received_packet_pos))
                        {
                            // packet decoded -> check CRC
                            if (received_packet_pos > (Marshal.SizeOf(typeof(PacketBase)) + PacketConstants.PacketCRCLength))
                            {
                                m_received_packet_length = received_packet_pos;
                                crc = CRC16.CalculateForBlock(CRC16.InitValue, m_receive_packet_buffer, m_received_packet_length - PacketConstants.PacketCRCLength);

                                if (ByteAccess.LowByte(crc) == m_receive_packet_buffer[m_received_packet_length - 2] && ByteAccess.HighByte(crc) == m_receive_packet_buffer[m_received_packet_length - 1])
                                {
                                    // CRC OK -> continue processing received packet
                                    PacketType type = (PacketType)m_receive_data_buffer[PacketConstants.TypeOffset];

                                    // update statistics
                                    Interlocked.Add(ref m_upstream_bytes, m_received_data_length);

                                    // process received data
                                    if (m_received_packet_length <= PacketConstants.PacketMaxLength)
                                    {
                                        m_communication_manager.StoreReceivedPacket(m_communication_channel_index, m_receive_packet_buffer, (byte)m_received_packet_length);
                                    }
                                }
                            }
                            // restart packet decoding
                            received_packet_pos = 0;
                        }

                        m_read_pending = false;
                    }
                }

                // restart reception
                if (!m_read_pending)
                {
                    try
                    {
                        m_received_data_length = 0;
                        m_read_pending         = true;
                        m_serial_port.BaseStream.BeginRead(m_receive_data_buffer, 0, m_receive_data_buffer.Length, m_receiver_callback, this);
                    }
                    catch
                    {
                        // stop thread because of the unexpected error
                        m_stop_requested = true;
                        m_thread_event.Set();
                    }
                }
            }

            // close socket
            m_serial_port.Close();
            m_serial_port = null;

            // thread is finished
            m_thread_stopped.Set();
        }
示例#13
0
文件: Screen.cs 项目: scemino/nscumm
        private void BlitBlockClear(ushort x, ushort y, ByteAccess data)
        {
            var dest = y * SCRNGRID_Y * _scrnSizeX + x * SCRNGRID_X;

            for (byte cnty = 0; cnty < (SystemVars.Platform == Platform.PSX ? SCRNGRID_Y / 2 : SCRNGRID_Y); cnty++)
            {
                for (byte cntx = 0; cntx < SCRNGRID_X; cntx++)
                    if (data[cntx] != 0)
                        _screenBuf[dest + cntx] = data[cntx];

                if (SystemVars.Platform == Platform.PSX)
                {
                    dest += _scrnSizeX;
                    for (byte cntx = 0; cntx < SCRNGRID_X; cntx++)
                        if (data[cntx] != 0)
                            _screenBuf[dest + cntx] = data[cntx];
                }

                data.Offset += SCRNGRID_X;
                dest += _scrnSizeX;
            }
        }
示例#14
0
文件: Screen.cs 项目: scemino/nscumm
        private void FastShrink(ByteAccess src, ushort width, ushort height, uint scale, byte[] dest)
        {
            uint resHeight = (height * scale) >> 8;
            uint resWidth = (width * scale) >> 8;
            uint step = 0x10000 / scale;
            byte[] columnTab = new byte[160];
            uint res = step >> 1;

            for (ushort cnt = 0; cnt < resWidth; cnt++)
            {
                columnTab[cnt] = (byte)(res >> 8);
                res += step;
            }

            uint newRow = step >> 1;
            uint oldRow = 0;

            var destPos = 0;
            var srcPos = 0;
            ushort lnCnt;
            for (lnCnt = 0; lnCnt < resHeight; lnCnt++)
            {
                while (oldRow < (newRow >> 8))
                {
                    oldRow++;
                    srcPos += width;
                }
                for (ushort colCnt = 0; colCnt < resWidth; colCnt++)
                {
                    dest[destPos++] = src[srcPos + columnTab[colCnt]];
                }
                newRow += step;
            }
            // scaled, now stipple shadows if there are any
            for (lnCnt = 0; lnCnt < resHeight; lnCnt++)
            {
                ushort xCnt = (ushort)(lnCnt & 1);
                destPos = (int)(lnCnt * resWidth + (lnCnt & 1));
                while (xCnt < resWidth)
                {
                    if (dest[destPos] == 200)
                        dest[destPos] = 0;
                    destPos += 2;
                    xCnt += 2;
                }
            }
        }
示例#15
0
文件: Screen.cs 项目: scemino/nscumm
 private void VertMaskSub(UShortAccess grid, int gridOfs, int screenPtr, uint layerId)
 {
     for (var cntx = 0; cntx < _sprHeight; cntx++)
     {
         // start_x | block_loop
         if (grid[gridOfs] != 0)
         {
             if ((grid[gridOfs] & 0x8000) == 0)
             {
                 var gridVal = grid[gridOfs] - 1;
                 gridVal *= GridW * GridH;
                 var dataSrc = new ByteAccess(SkyEngine.ItemList[Logic.ScriptVariables[(int) layerId]], gridVal);
                 var dataTrg = screenPtr;
                 for (var grdCntY = 0; grdCntY < GridH; grdCntY++)
                 {
                     for (var grdCntX = 0; grdCntX < GridW; grdCntX++)
                         if (dataSrc[grdCntX] != 0)
                             Current[dataTrg + grdCntX] = dataSrc[grdCntX];
                     dataSrc.Offset += GridW;
                     dataTrg += GameScreenWidth;
                 }
             } // dummy_end:
             screenPtr -= GridH * GameScreenWidth;
             gridOfs -= GridX;
         }
         else
             return;
     } // next_x
 }
示例#16
0
文件: Screen.cs 项目: scemino/nscumm
        private void DrawSprite(ByteAccess sprData, ushort sprX, ushort sprY, ushort sprWidth, ushort sprHeight, ushort sprPitch)
        {
            var dest = new ByteAccess(_screenBuf, sprY * _scrnSizeX + sprX);

            for (ushort cnty = 0; cnty < sprHeight; cnty++)
            {
                for (ushort cntx = 0; cntx < sprWidth; cntx++)
                    if (sprData[cntx] != 0)
                        dest[cntx] = sprData[cntx];

                if (SystemVars.Platform == Platform.PSX)
                { //On PSX version we need to double horizontal lines
                    dest.Offset += _scrnSizeX;
                    for (ushort cntx = 0; cntx < sprWidth; cntx++)
                        if (sprData[cntx] != 0)
                            dest[cntx] = sprData[cntx];
                }

                sprData.Offset += sprPitch;
                dest.Offset += _scrnSizeX;
            }
        }
示例#17
0
        private bool ProcessPatchSysEx(ByteAccess sysExData)
        {
            byte[] sysExBuf = new byte[15];
            byte crc = 0;
            if ((sysExData[0] & 0x80) != 0)
                return false;

            // decompress data from stream
            sysExBuf[0] = 0x41;
            sysExBuf[1] = 0x10;
            sysExBuf[2] = 0x16;
            sysExBuf[3] = 0x12;
            sysExBuf[4] = 0x5;
            sysExBuf[5] = (byte)(sysExData[0] >> 4);            // patch offset part 1
            sysExBuf[6] = (byte)((sysExData[0] & 0xF) << 3);    // patch offset part 2
            sysExBuf[7] = (byte)(sysExData[1] >> 6);            // timbre group
            sysExBuf[8] = (byte)(sysExData[1] & 0x3F);          // timbre num
            sysExBuf[9] = (byte)(sysExData[2] & 0x3F);          // key shift
            sysExBuf[10] = (byte)(sysExData[3] & 0x7F);         // fine tune
            sysExBuf[11] = (byte)(sysExData[4] & 0x7F);         // bender range
            sysExBuf[12] = (byte)(sysExData[2] >> 6);           // assign mode
            sysExBuf[13] = (byte)(sysExData[3] >> 7);           // reverb switch
            for (byte cnt = 4; cnt < 14; cnt++)
                crc -= sysExBuf[cnt];
            sysExBuf[14] = (byte)(crc & 0x7F);                  // crc
            _midiDrv.SysEx(sysExBuf, 15);
            // We delay the time it takes to send the sysEx plus an
            // additional 40ms, which is required for MT-32 rev00,
            // to assure no buffer overflow or missing bytes
            ServiceLocator.Platform.Sleep(17 * 1000 / 3125 + 40);
            return true;
        }
示例#18
0
文件: Screen.cs 项目: scemino/nscumm
        private void ProcessImage(uint id)
        {
            FrameHeader frameHead;
            int scale;

            var compact = _objMan.FetchObject(id);

            if (compact.type == TYPE_TEXT)
                frameHead = new FrameHeader(_textMan.GiveSpriteData((byte)compact.target));
            else
                frameHead = new FrameHeader(_resMan.FetchFrame(_resMan.OpenFetchRes((uint)compact.resource), (uint)compact.frame));

            ushort spriteX = (ushort)compact.anim_x;
            ushort spriteY = (ushort)compact.anim_y;


            if ((compact.status & STAT_SHRINK) != 0)
            {
                scale = (compact.scale_a * compact.ycoord + compact.scale_b) / 256;
                spriteX = (ushort)(spriteX + (_resMan.ReadInt16(frameHead.offsetX) * scale) / 256);
                spriteY = (ushort)(spriteY + (_resMan.ReadInt16(frameHead.offsetY) * scale) / 256);
            }
            else
            {
                scale = 256;
                spriteX = (ushort)(spriteX + _resMan.ReadInt16(frameHead.offsetX));
                spriteY = (ushort)(spriteY + _resMan.ReadInt16(frameHead.offsetY));
            }

            var sprData = new ByteAccess(frameHead.Data.Data, frameHead.Data.Offset + FrameHeader.Size);
            if (SystemVars.Platform == Platform.PSX && compact.type != TYPE_TEXT)
            {
                // PSX sprites are compressed with HIF
                var hifBuf = new byte[_resMan.ReadUInt16(frameHead.width) * _resMan.ReadUInt16(frameHead.height) / 2];
                DecompressHIF(sprData.Data, sprData.Offset, hifBuf);
                sprData = new ByteAccess(hifBuf);
            }
            else if (frameHead.runTimeComp[3] == '7')
            { // RLE7 encoded?
                DecompressRLE7(sprData.Data, sprData.Offset, _resMan.ReadUInt32(frameHead.compSize), _rleBuffer);
                sprData = new ByteAccess(_rleBuffer);
            }
            else if (frameHead.runTimeComp[3] == '0')
            { // RLE0 encoded?
                DecompressRLE0(sprData.Data, sprData.Offset, _resMan.ReadUInt32(frameHead.compSize), _rleBuffer);
                sprData = new ByteAccess(_rleBuffer);
            }
            else if (frameHead.runTimeComp[1] == 'I')
            { // new type
                var tonyBuf = new byte[_resMan.ReadUInt32(frameHead.width) * _resMan.ReadUInt16(frameHead.height)];
                DecompressTony(sprData.Data, sprData.Offset, _resMan.ReadUInt32(frameHead.compSize), tonyBuf);
                sprData = new ByteAccess(tonyBuf);
            }

            ushort sprSizeX, sprSizeY;
            if ((compact.status & STAT_SHRINK) != 0)
            {
                //Clean shrink buffer to avoid corruption
                Array.Clear(_shrinkBuffer, 0, SHRINK_BUFFER_SIZE);
                if (SystemVars.Platform == Platform.PSX && (compact.resource != SwordRes.GEORGE_MEGA))
                {
                    // PSX Height shrinked sprites
                    sprSizeX = (ushort)((scale * _resMan.ReadUInt16(frameHead.width)) / 256);
                    sprSizeY = (ushort)((scale * (_resMan.ReadUInt16(frameHead.height))) / 256 / 2);
                    FastShrink(sprData, _resMan.ReadUInt16(frameHead.width), (ushort)((_resMan.ReadUInt16(frameHead.height)) / 2), (uint)scale, _shrinkBuffer);
                }
                else if (SystemVars.Platform == Platform.PSX)
                {
                    // PSX width/height shrinked sprites
                    sprSizeX = (ushort)((scale * _resMan.ReadUInt16(frameHead.width)) / 256 / 2);
                    sprSizeY = (ushort)((scale * _resMan.ReadUInt16(frameHead.height)) / 256 / 2);
                    FastShrink(sprData, (ushort)(_resMan.ReadUInt16(frameHead.width) / 2), (ushort)(_resMan.ReadUInt16(frameHead.height) / 2), (uint)scale, _shrinkBuffer);
                }
                else
                {
                    sprSizeX = (ushort)(scale * _resMan.ReadUInt16(frameHead.width) / 256);
                    sprSizeY = (ushort)(scale * _resMan.ReadUInt16(frameHead.height) / 256);
                    FastShrink(sprData, _resMan.ReadUInt16(frameHead.width), _resMan.ReadUInt16(frameHead.height), (uint)scale, _shrinkBuffer);
                }
                sprData = new ByteAccess(_shrinkBuffer);
            }
            else
            {
                sprSizeX = _resMan.ReadUInt16(frameHead.width);
                if (SystemVars.Platform == Platform.PSX)
                {
                    // PSX sprites are half height
                    sprSizeY = (ushort)(_resMan.ReadUInt16(frameHead.height) / 2);
                }
                else
                    sprSizeY = _resMan.ReadUInt16(frameHead.height);
            }

            if ((compact.status & STAT_OVERRIDE) == 0)
            {
                //mouse size linked to exact size & coordinates of sprite box - shrink friendly
                if (_resMan.ReadUInt16((ushort)frameHead.offsetX) != 0 || _resMan.ReadUInt16((ushort)frameHead.offsetY) != 0)
                {
                    //for megas the mouse area is reduced to account for sprite not
                    //filling the box size is reduced to 1/2 width, 4/5 height
                    compact.mouse_x1 = spriteX + sprSizeX / 4;
                    compact.mouse_x2 = spriteX + 3 * sprSizeX / 4;
                    compact.mouse_y1 = spriteY + sprSizeY / 10;
                    compact.mouse_y2 = spriteY + 9 * sprSizeY / 10;
                }
                else
                {
                    compact.mouse_x1 = spriteX;
                    compact.mouse_x2 = spriteX + sprSizeX;
                    compact.mouse_y1 = spriteY;
                    compact.mouse_y2 = spriteY + sprSizeY;
                }
            }

            ushort sprPitch = sprSizeX;
            ushort incr;
            SpriteClipAndSet(ref spriteX, ref spriteY, ref sprSizeX, ref sprSizeY, out incr);

            if ((sprSizeX > 0) && (sprSizeY > 0))
            {
                if (SystemVars.Platform != Platform.PSX || (compact.type == TYPE_TEXT)
                    || (compact.resource == SwordRes.LVSFLY) || (compact.resource != SwordRes.GEORGE_MEGA && (sprSizeX < 260)))
                {
                    sprData.Offset += incr;
                    DrawSprite(sprData, spriteX, spriteY, sprSizeX, sprSizeY, sprPitch);
                }
                else if (((sprSizeX >= 260) && (sprSizeX < 450)) || ((compact.resource == SwordRes.GMWRITH) && (sprSizeX < 515))
                         // a psx shrinked sprite (1/2 width)
                         || ((compact.resource == SwordRes.GMPOWER) && (sprSizeX < 515)))
                {
                    // some needs to be hardcoded, headers don't give useful infos
                    DrawPsxHalfShrinkedSprite(sprData.Data, sprData.Offset + incr, spriteX, spriteY, (ushort)(sprSizeX / 2), sprSizeY, (ushort)(sprPitch / 2));
                }
                else if (sprSizeX >= 450) // A PSX double shrinked sprite (1/3 width)
                {
                    DrawPsxFullShrinkedSprite(sprData.Data, sprData.Offset + incr, spriteX, spriteY, (ushort)(sprSizeX / 3), sprSizeY, (ushort)(sprPitch / 3));
                }
                else // This is for psx half shrinked, walking george and remaining sprites
                {
                    DrawPsxHalfShrinkedSprite(sprData.Data, sprData.Offset + incr, spriteX, spriteY, sprSizeX, sprSizeY, sprPitch);
                }
                if ((compact.status & STAT_FORE) == 0 &&
                    !(SystemVars.Platform == Platform.PSX && (compact.resource == SwordRes.MOUBUSY)))
                // Check fixes moue sprite being masked by layer, happens only on psx
                {
                    VerticalMask(spriteX, spriteY, sprSizeX, sprSizeY);
                }
            }

            if (compact.type != TYPE_TEXT)
                _resMan.ResClose((uint)compact.resource);
        }
示例#19
0
文件: Screen.cs 项目: scemino/nscumm
 public FrameHeader(ByteAccess data)
 {
     Data = data;
 }
示例#20
0
文件: Screen.cs 项目: scemino/nscumm
        public void ShowFrame(ushort x, ushort y, uint resId, uint frameNo, byte[] fadeMask = null, sbyte fadeStatus = 0)
        {
            byte[] frame = new byte[40 * 40];
            int i, j;

            // PSX top menu is black
            if (SystemVars.Platform != Platform.PSX)
            {
                // Dark gray background
                frame.Set(0, 199, frame.Length);
            }

            if (resId != 0xffffffff)
            {
                FrameHeader frameHead = new FrameHeader(_resMan.FetchFrame(_resMan.OpenFetchRes(resId), frameNo));
                var frameData = new ByteAccess(frameHead.Data.Data, frameHead.Data.Offset + FrameHeader.Size);

                if (SystemVars.Platform == Platform.PSX)
                {
                    //We need to decompress PSX frames
                    var frameBufferPSX = new byte[_resMan.ReadUInt16(frameHead.width) * _resMan.ReadUInt16(frameHead.height) / 2];
                    DecompressHIF(frameData.Data, frameData.Offset, frameBufferPSX);

                    for (i = 0; i < _resMan.ReadUInt16(frameHead.height) / 2; i++)
                    {
                        for (j = 0; j < _resMan.ReadUInt16(frameHead.width); j++)
                        {
                            var data = frameBufferPSX[i * _resMan.ReadUInt16(frameHead.width) + j];
                            frame[(i * 2 + 4) * 40 + j + 2] = data;
                            frame[(i * 2 + 1 + 4) * 40 + j + 2] = data; //Linedoubling the sprite
                        }
                    }
                }
                else
                {
                    for (i = 0; i < _resMan.ReadUInt16(frameHead.height); i++)
                        for (j = 0; j < _resMan.ReadUInt16(frameHead.height); j++)
                            frame[(i + 4) * 40 + j + 2] = frameData[i * _resMan.ReadUInt16(frameHead.width) + j];
                }

                _resMan.ResClose(resId);
            }

            if (fadeMask != null)
            {
                for (i = 0; i < 40; i++)
                {
                    for (j = 0; j < 40; j++)
                    {
                        if (fadeMask[((i % 8) * 8) + (j % 8)] >= fadeStatus)
                            frame[i * 40 + j] = 0;
                    }
                }
            }

            _system.GraphicsManager.CopyRectToScreen(frame, 40, x, y, 40, 40);
        }
示例#21
0
文件: Screen.cs 项目: scemino/nscumm
        public void NewScreen(uint screen)
        {
            // set sizes and scrolling, initialize/load screengrid, force screen refresh
            _currentScreen = (ushort)screen;
            _scrnSizeX = (ushort)SwordRes.RoomDefTable[screen].sizeX;
            _scrnSizeY = (ushort)SwordRes.RoomDefTable[screen].sizeY;
            _gridSizeX = (ushort)(_scrnSizeX / SCRNGRID_X);
            _gridSizeY = (ushort)(_scrnSizeY / SCRNGRID_Y);
            if (_scrnSizeX % SCRNGRID_X != 0 || _scrnSizeY % SCRNGRID_Y != 0)
                throw new InvalidOperationException($"Illegal screensize: {screen}: {_scrnSizeX}/{_scrnSizeY}");
            if ((_scrnSizeX > SCREEN_WIDTH) || (_scrnSizeY > SCREEN_DEPTH))
            {
                Logic.ScriptVars[(int)ScriptVariableNames.SCROLL_FLAG] = 2;
                Logic.ScriptVars[(int)ScriptVariableNames.MAX_SCROLL_OFFSET_X] = (uint)(_scrnSizeX - SCREEN_WIDTH);
                Logic.ScriptVars[(int)ScriptVariableNames.MAX_SCROLL_OFFSET_Y] = (uint)(_scrnSizeY - SCREEN_DEPTH);
            }
            else
            {
                Logic.ScriptVars[(int)ScriptVariableNames.SCROLL_FLAG] = 0;
                Logic.ScriptVars[(int)ScriptVariableNames.MAX_SCROLL_OFFSET_X] = 0;
                Logic.ScriptVars[(int)ScriptVariableNames.MAX_SCROLL_OFFSET_Y] = 0;
            }
            Logic.ScriptVars[(int)ScriptVariableNames.SCROLL_OFFSET_X] = 0;
            Logic.ScriptVars[(int)ScriptVariableNames.SCROLL_OFFSET_Y] = 0;

            if (SystemVars.Platform == Platform.PSX)
                FlushPsxCache();

            _screenBuf = new byte[_scrnSizeX * _scrnSizeY];
            _screenGrid = new byte[_gridSizeX * _gridSizeY];

            for (var cnt = 0; cnt < SwordRes.RoomDefTable[_currentScreen].totalLayers; cnt++)
            {
                // open and lock all resources, will be closed in quitScreen()
                _layerBlocks[cnt] = new ByteAccess(_resMan.OpenFetchRes(SwordRes.RoomDefTable[_currentScreen].layers[cnt]));
                if (cnt > 0)
                    _layerBlocks[cnt].Offset += Header.Size;
            }
            for (var cnt = 0; cnt < SwordRes.RoomDefTable[_currentScreen].totalLayers - 1; cnt++)
            {
                // there's no grid for the background layer, so it's totalLayers - 1
                _layerGrid[cnt] = new UShortAccess(_resMan.OpenFetchRes(SwordRes.RoomDefTable[_currentScreen].grids[cnt]));
                _layerGrid[cnt].Offset += 14 * 2;
            }
            _parallax[0] = _parallax[1] = null;
            if (SwordRes.RoomDefTable[_currentScreen].parallax[0] != 0)
                _parallax[0] = _resMan.OpenFetchRes(SwordRes.RoomDefTable[_currentScreen].parallax[0]);
            if (SwordRes.RoomDefTable[_currentScreen].parallax[1] != 0)
                _parallax[1] = _resMan.OpenFetchRes(SwordRes.RoomDefTable[_currentScreen].parallax[1]);

            _updatePalette = true;
            _fullRefresh = true;
        }
示例#22
0
文件: Screen.cs 项目: scemino/nscumm
        // needed because some psx backgrounds are half width and half height
        private byte[] PsxShrinkedBackgroundToIndexed(byte[] psxBackground, int offset, int bakXres, int bakYres)
        {
            int xresInTiles = ((bakXres / 2) % 16) != 0 ? (bakXres / 32) + 1 : (bakXres / 32);
            int yresInTiles = ((bakYres / 2) % 16) != 0 ? (bakYres / 32) + 1 : (bakYres / 32);
            int totTiles = xresInTiles * yresInTiles;
            int tileYpos = 0; //tile position in a virtual xresInTiles * yresInTiles grid
            int tileXpos = 0;
            uint dataBegin = psxBackground.ToUInt32(offset + 4);

            var decomp_tile = new byte[16 * 16]; //Tiles are always 16 * 16
            var fullres_buffer = new byte[bakXres * (yresInTiles + 1) * 32];

            bool isCompressed = (psxBackground.ToUInt32(offset) == ScummHelper.MakeTag('C', 'O', 'M', 'P'));

            totTiles -= xresInTiles;
            var b = offset + 4; //We skip the id tag

            int currentTile;
            for (currentTile = 0; currentTile < totTiles; currentTile++)
            {
                int tileOffset = psxBackground.ToInt32(b + 4 * currentTile);

                if (isCompressed)
                {
                    DecompressHIF(psxBackground, b + tileOffset - 4, decomp_tile); //Decompress the tile into decomp_tile
                }
                else {
                    Array.Copy(psxBackground, b + tileOffset - 4, decomp_tile, 0, 16 * 16);
                }

                if (currentTile > 0 && (currentTile % xresInTiles) == 0)
                { //Finished a line of tiles, going down
                    tileYpos++;
                    tileXpos = 0;
                }

                for (byte tileLine = 0; tileLine < 16; tileLine++)
                {
                    var dest = new ByteAccess(fullres_buffer, tileLine * bakXres * 2 + tileXpos * 32 + tileYpos * bakXres * 16 * 2);
                    for (byte tileColumn = 0; tileColumn < 16; tileColumn++)
                    {
                        byte pixData = decomp_tile[tileColumn + tileLine * 16];
                        dest[tileColumn * 2] = pixData;
                        dest[tileColumn * 2 + 1] = pixData;
                    }
                    dest.Offset += bakXres;
                    for (byte tileColumn = 0; tileColumn < 16; tileColumn++)
                    {
                        var pixData = decomp_tile[tileColumn + tileLine * 16];
                        dest[tileColumn * 2] = pixData;
                        dest[tileColumn * 2 + 1] = pixData;
                    }

                }
                tileXpos++;
            }

            //Calculate number of remaining tiles
            uint remainingTiles = (uint)((dataBegin - (currentTile * 4 + 4)) / 4);

            // Last line of tiles is full width!
            uint tileHeight = (remainingTiles == xresInTiles * 2) ? 16U : 8;

            tileXpos = 0;
            for (; currentTile < totTiles + remainingTiles; currentTile++)
            {
                int tileOffset = psxBackground.ToInt32(b + 4 * currentTile);

                if (isCompressed)
                {
                    DecompressHIF(psxBackground, b + tileOffset - 4, decomp_tile); //Decompress the tile into decomp_tile
                }
                else {
                    Array.Copy(psxBackground, b + tileOffset - 4, decomp_tile, 0, 256);
                }

                for (byte tileLine = 0; tileLine < tileHeight; tileLine++)
                { // Write the decoded tiles into last lines of background
                    Array.Copy(decomp_tile, tileLine * 16, fullres_buffer, tileXpos * 16 + (tileLine + (yresInTiles - 1) * 16) * bakXres * 2, 16);
                    Array.Copy(decomp_tile, tileLine * 16, fullres_buffer, tileXpos * 16 + (tileLine + (yresInTiles - 1) * 16) * bakXres * 2 + bakXres, 16);
                }
                tileXpos++;
            }

            return fullres_buffer;
        }
示例#23
0
文件: Screen.cs 项目: scemino/nscumm
        private void DrawPsxParallax(byte[] psxParallax, ushort paraScrlX, ushort scrnScrlX, ushort scrnWidth)
        {
            ushort totTiles = psxParallax.ToUInt16(14); // Total tiles

            ushort skipRow = (ushort)(paraScrlX / 16); // Rows of tiles we have to skip
            byte leftPixelSkip = (byte)(paraScrlX % 16); // Pixel columns we have to skip while drawing the first row

            var plxPos = new ByteAccess(psxParallax, 16); // Pointer to tile position header section
            var plxOff = new ByteAccess(psxParallax, 16 + totTiles * 2); // Pointer to tile relative offsets section
            var plxData = new ByteAccess(psxParallax, 16 + totTiles * 2 + totTiles * 4); //Pointer to beginning of tiles data section

            var tile_buffer = new byte[16 * 16]; // Buffer for 16x16 pix tile

            /* For parallax rendering we should check both horizontal and vertical scrolling,
             * but in PSX edition of the game, the only vertical scrolling parallax is disabled.
             * So, in this function i'll only check for horizontal scrolling.
             */

            for (ushort currentTile = 0; currentTile < totTiles - 1; currentTile++)
            {
                byte tileXpos = plxPos[2 * currentTile]; // Fetch tile X and Y position in the grid
                byte tileYpos = (byte)(plxPos[2 * currentTile + 1] * 2);
                int tileBegin = (tileXpos * 16) - paraScrlX;
                tileBegin = (tileBegin < 0) ? 0 : tileBegin;
                ushort currentLine = (ushort)(tileYpos * 16); //Current line of the image we are drawing upon, used to avoid going out of screen

                if (tileXpos >= skipRow)
                { // Tiles not needed in the screen buffer are not uncompressed
                    int tileOffset = plxOff.Data.ToInt32(plxOff.Offset + 4 * currentTile);
                    ushort rightScreenLimit = (ushort)(_scrnSizeX - scrnScrlX); // Do not write over and beyond this limit, lest we get memory corruption
                    var dest = new ByteAccess(_screenBuf, (tileYpos * 16 * _scrnSizeX) + tileBegin + scrnScrlX);
                    var src = new ByteAccess(tile_buffer);

                    DecompressHIF(plxData.Data, plxData.Offset + tileOffset, tile_buffer); // Decompress the tile

                    if (tileXpos != skipRow)
                    { // This tile will surely be drawn fully in the buffer
                        for (byte tileLine = 0; (tileLine < 16) && (currentLine < SCREEN_DEPTH); tileLine++)
                        { // Check that we are not going outside the bottom screen part
                            for (byte tileColumn = 0; (tileColumn < 16) && (tileBegin + tileColumn) < rightScreenLimit; tileColumn++)
                                if (src[tileColumn] != 0)
                                    dest[tileColumn] = src[tileColumn];
                            dest.Offset += _scrnSizeX;
                            currentLine++;

                            if (currentLine < SCREEN_DEPTH)
                            {
                                for (byte tileColumn = 0; (tileColumn < 16) && (tileBegin + tileColumn) < rightScreenLimit; tileColumn++)
                                    if (src[tileColumn] != 0)
                                        dest[tileColumn] = src[tileColumn];
                                dest.Offset += _scrnSizeX;
                                currentLine++;
                            }
                            src.Offset += 16; // get to next line of decoded tile
                        }
                    }
                    else { // This tile may be drawn only partially
                        src.Offset += leftPixelSkip; //Skip hidden pixels
                        for (byte tileLine = 0; (tileLine < 16) && (currentLine < SCREEN_DEPTH); tileLine++)
                        {
                            for (byte tileColumn = 0; tileColumn < (16 - leftPixelSkip); tileColumn++)
                                if (src[tileColumn] != 0)
                                    dest[tileColumn] = src[tileColumn];
                            dest.Offset += _scrnSizeX;
                            currentLine++;

                            if (currentLine < SCREEN_DEPTH)
                            {
                                for (byte tileColumn = 0; tileColumn < (16 - leftPixelSkip); tileColumn++)
                                    if (src[tileColumn] != 0)
                                        dest[tileColumn] = src[tileColumn];
                                dest.Offset += _scrnSizeX;
                                currentLine++;
                            }
                            src.Offset += 16;
                        }
                    }
                }
            }
        }
示例#24
0
文件: Screen.cs 项目: scemino/nscumm
        // Used to draw psx sprites which are 1/3 of original width
        private void DrawPsxFullShrinkedSprite(byte[] sprData, int offset, ushort sprX, ushort sprY, ushort sprWidth, ushort sprHeight, ushort sprPitch)
        {
            var dest = new ByteAccess(_screenBuf, (sprY * _scrnSizeX) + sprX);
            var data = new ByteAccess(sprData, offset);

            for (ushort cnty = 0; cnty < sprHeight; cnty++)
            {
                for (ushort cntx = 0; cntx < sprWidth; cntx++)
                    if (data[cntx] != 0)
                    {
                        dest[cntx * 3] = data[cntx]; //In these sprites we need to double vertical lines too...
                        dest[cntx * 3 + 1] = data[cntx];
                        dest[cntx * 3 + 2] = data[cntx];
                    }

                dest.Offset += _scrnSizeX;
                for (ushort cntx = 0; cntx < sprWidth; cntx++)
                    if (data[cntx] != 0)
                    {
                        dest[cntx * 3] = data[cntx];
                        dest[cntx * 3 + 1] = data[cntx];
                        dest[cntx * 3 + 2] = data[cntx];
                    }

                data.Offset += sprPitch;
                dest.Offset += _scrnSizeX;
            }
        }
        /// <summary>
        /// Main thread function
        /// </summary>
        public void Run()
        {
            bool          event_occured;
            int           i;
            UInt16        crc;
            AsyncCallback receiver_callback = new AsyncCallback(ReceiveCallback);

            // create endpoints
            m_receiver_endpoint = new IPEndPoint(IPAddress.Any, UDPLocalPort);

            // init socket
            m_timestamp = DateTime.MinValue;

            m_client                 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            m_client.Blocking        = false;
            m_client.EnableBroadcast = true;
            m_client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            m_client.Bind(m_receiver_endpoint);

            // init
            m_upstream_bytes   = 0;
            m_downstream_bytes = 0;

            // start data reception
            m_client.BeginReceive(m_receive_buffer, 0, m_receive_buffer.Length, 0, receiver_callback, this);

            // communication loop
            while (!m_stop_requested)
            {
                // wait for event
                event_occured = m_thread_event.WaitOne(ThreadWaitTimeout);

                // exit loop if thread must be stopped
                if (m_stop_requested)
                {
                    break;
                }

                // process received data
                if (m_received_data_length > 0)
                {
                    if (m_received_data_length > 2)
                    {
                        // check CRC
                        crc = CRC16.CalculateForBlock(CRC16.InitValue, m_receive_buffer, m_received_data_length - 2);

                        if (ByteAccess.LowByte(crc) == m_receive_buffer[m_received_data_length - 2] && ByteAccess.HighByte(crc) == m_receive_buffer[m_received_data_length - 1])
                        {
                            // CRC OK -> continue processing received packet
                            PacketType type = (PacketType)m_receive_buffer[PacketConstants.TypeOffset];

                            // update statistics
                            Interlocked.Add(ref m_upstream_bytes, m_received_data_length);

                            // process received packet
                            switch (type)
                            {
                            // process device annnounce packet
                            case PacketType.CommDeviceAnnounce:
                            {
                                PacketDeviceAnnounce device_info;

                                // get announce packet
                                device_info = (PacketDeviceAnnounce)RawBinarySerialization.DeserializeObject(m_receive_buffer, typeof(PacketDeviceAnnounce));

                                // check if it is already on the list of active devices
                                DeviceInfo current_device_info = m_detected_devices.Find(x => x.UniqueID == device_info.UniqueID);

                                if (current_device_info != null)
                                {
                                    // device is on the list
                                    current_device_info.HostAnnouncePending = true;
                                    current_device_info.LastInfoTimestamp   = DateTime.Now;
                                }
                                else
                                {
                                    DeviceInfo new_device = new DeviceInfo(device_info);
                                    new_device.HostAnnouncePending = true;

                                    if (new_device.Address != IPAddress.None)
                                    {
                                        m_detected_devices.Add(new_device);
                                        if (m_detected_devices.Count == 1)
                                        {
                                            lock (m_detected_devices)
                                            {
                                                m_current_device = m_detected_devices[0];
                                            }
                                        }
                                    }
                                }
                            }
                            break;

                            default:
                                // process received data
                                if (m_received_data_length <= PacketConstants.PacketMaxLength)
                                {
                                    m_communication_manager.StoreReceivedPacket(m_communication_channel_index, m_receive_buffer, (byte)m_received_data_length);
                                }
                                break;
                            }
                        }
                    }

                    // restart reception
                    try
                    {
                        m_received_data_length = 0;
                        m_client.BeginReceive(m_receive_buffer, 0, m_receive_buffer.Length, 0, receiver_callback, this);
                    }
                    catch
                    {
                        // TODO: error handling
                    }
                }

                // send host announce for devices
                for (i = 0; i < m_detected_devices.Count; i++)
                {
                    IPAddress address_mask = new IPAddress(new byte[] { 255, 255, 255, 0 });

                    if (m_detected_devices[i].HostAnnouncePending)
                    {
                        IPAddress local_ip = GetLocalIPAddress(m_detected_devices[i].Address, address_mask);

                        if (m_sender_lock.Wait(0))
                        {
                            // create host info packet
                            PacketHostAnnounce info = new PacketHostAnnounce();

                            info.Address = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(local_ip.GetAddressBytes(), 0));

                            byte[] packet = RawBinarySerialization.SerializeObject(info);

                            // send host info packet
                            EndPoint transmitter_endpoint = new IPEndPoint(m_detected_devices[i].Address, UDPRemotePort);

                            InternalPacketSend(transmitter_endpoint, packet);

                            m_detected_devices[i].HostAnnouncePending = false;
                        }
                    }
                }

                // delete unreachable or connectecd devices from the list
                DateTime current_timestamp = DateTime.Now;
                i = 0;
                while (i < m_detected_devices.Count)
                {
                    // if devlice is silent for a while -> remove from the list
                    if ((current_timestamp - m_detected_devices[i].LastInfoTimestamp).TotalMilliseconds > DeviceAnnounceTimeout)
                    {
                        m_detected_devices.RemoveAt(i);
                    }
                    else
                    {
                        i++;
                    }
                }
            }

            // close socket
            m_client.Shutdown(SocketShutdown.Both);
            Thread.Sleep(10);
            m_client.Close();

            // thread is finished
            m_thread_stopped.Set();
        }
示例#26
0
 protected override void SetupPointers()
 {
     _musicDataLoc  = _musicData.ToUInt16(0x7DC);
     _sysExSequence = new ByteAccess(_musicData, _musicData.ToUInt16(0x7E0));
 }
示例#27
0
    private Result TxRxAscii(byte[] TXBuf, int QueryLength, byte[] RXBuf, int ResponseLength)
    {
        var num    = 0;
        var array  = new byte[531];
        var array2 = new byte[523];

        Ascii.RTU2ASCII(TXBuf, QueryLength, array);
        var n = Ascii.LRC(TXBuf, QueryLength);

        array[0] = 58;
        array[QueryLength * 2 + 1] = Ascii.Num2Ascii(ByteAccess.HI4BITS(n));
        array[QueryLength * 2 + 2] = Ascii.Num2Ascii(ByteAccess.LO4BITS(n));
        array[QueryLength * 2 + 3] = 13;
        array[QueryLength * 2 + 4] = 10;
        this.port.DiscardInBuffer();
        this.port.DiscardOutBuffer();
        try
        {
            this.port.Write(array, 0, QueryLength * 2 + 5);
        }
        catch (Exception ex)
        {
            this.Error = ex.Message;
            return(Result.WRITE);
        }

        this._txBufSize = QueryLength * 2 + 5;
        Array.Copy(array, this._txBuf, this._txBufSize);
        if (TXBuf[0] == 0)
        {
            return(Result.SUCCESS);
        }
        if (this._removeEcho)
        {
            try
            {
                do
                {
                    var num2 = this.port.Read(RXBuf, 0, this._txBufSize - num);
                    num += num2;
                }while (this._txBufSize - num > 0);
            }
            catch (TimeoutException ex2)
            {
                this.Error = ex2.Message;
                return(Result.RESPONSE_TIMEOUT);
            }
            catch (Exception ex3)
            {
                this.Error = ex3.Message;
                return(Result.READ);
            }

            num = 0;
        }

        try
        {
            do
            {
                var num3 = this.port.Read(array2, num, 11 - num);
                num += num3;
            }while (11 - num > 0);
        }
        catch (TimeoutException ex4)
        {
            this.Error = ex4.Message;
            return(Result.RESPONSE_TIMEOUT);
        }
        catch (Exception ex5)
        {
            this.Error = ex5.Message;
            return(Result.READ);
        }
        finally
        {
            this._rxBufSize = num;
            Array.Copy(array2, this._rxBuf, this._rxBufSize);
        }

        if (Ascii.HiLo4BitsToByte(Ascii.Ascii2Num(array2[3]), Ascii.Ascii2Num(array2[4])) > 128)
        {
            if (!Ascii.VerifyRespLRC(array2, 11))
            {
                return(Result.CRC);
            }
            return((Result)Ascii.HiLo4BitsToByte(Ascii.Ascii2Num(array2[5]), Ascii.Ascii2Num(array2[6])));
        }

        if (ResponseLength == int.MaxValue)
        {
            if (Ascii.HiLo4BitsToByte(Ascii.Ascii2Num(array2[3]), Ascii.Ascii2Num(array2[4])) != 17)
            {
                return(Result.RESPONSE);
            }
            ResponseLength = Ascii.HiLo4BitsToByte(Ascii.Ascii2Num(array2[5]), Ascii.Ascii2Num(array2[6])) + 3;
        }

        try
        {
            var num4 = ResponseLength * 2 + 5;
            do
            {
                var num5 = this.port.Read(array2, num, num4 - num);
                num += num5;
            }while (num4 - num > 0);
        }
        catch (TimeoutException ex6)
        {
            this.Error = ex6.Message;
            return(Result.RESPONSE_TIMEOUT);
        }
        catch (Exception ex7)
        {
            this.Error = ex7.Message;
            return(Result.READ);
        }
        finally
        {
            this._rxBufSize = num;
            Array.Copy(array2, this._rxBuf, this._rxBufSize);
        }

        if (!Ascii.VerifyRespLRC(array2, num))
        {
            return(Result.CRC);
        }
        if (array2[num - 2] != 13 || array2[num - 1] != 10)
        {
            return(Result.RESPONSE);
        }
        var num6 = (num - 5) / 2;

        for (var i = 0; i < num6; i++)
        {
            RXBuf[i] = Ascii.HiLo4BitsToByte(Ascii.Ascii2Num(array2[1 + i * 2]), Ascii.Ascii2Num(array2[2 + i * 2]));
        }
        return(Result.SUCCESS);
    }
示例#28
0
 public void MegaEntering(ushort section)
 {
     _liveList[section]++;
     if (_liveList[section] == 1)
         _cptData[section] = new ByteAccess(_resMan.CptResOpen(_objectList[section]), Header.Size);
 }
示例#29
0
 protected override void SetupPointers()
 {
     _musicDataLoc = _musicData.ToUInt16(0x7DC);
     _sysExSequence = new ByteAccess(_musicData, _musicData.ToUInt16(0x7E0));
 }
示例#30
0
文件: Control.cs 项目: scemino/nscumm
        private void RenderVolumeBar(byte id, byte volL, byte volR)
        {
            ushort destX = (ushort)(_volumeButtons[id].x + 20);
            ushort destY = (ushort)(_volumeButtons[id].y + 116);

            for (var chCnt = 0; chCnt < 2; chCnt++)
            {
                byte vol = (chCnt == 0) ? volL : volR;
                FrameHeader frHead = new FrameHeader(_resMan.FetchFrame(_resMan.OpenFetchRes(SwordRes.SR_VLIGHT), (uint)((vol + 15) >> 4)));
                var destMem = new ByteAccess(_screenBuf, destY * Screen.SCREEN_WIDTH + destX);
                var srcMem = new ByteAccess(frHead.Data.Data, frHead.Data.Offset + FrameHeader.Size);
                ushort barHeight = _resMan.ReadUInt16(frHead.height);
                byte[] psxVolBuf = null;

                if (SystemVars.Platform == Platform.PSX)
                {
                    psxVolBuf = new byte[_resMan.ReadUInt16(frHead.height) / 2 * _resMan.ReadUInt16(frHead.width)];
                    Screen.DecompressHIF(srcMem.Data, srcMem.Offset, psxVolBuf);
                    srcMem = new ByteAccess(psxVolBuf);
                    barHeight /= 2;
                }

                for (ushort cnty = 0; cnty < barHeight; cnty++)
                {
                    Array.Copy(srcMem.Data, srcMem.Offset, destMem.Data, destMem.Offset, _resMan.ReadUInt16(frHead.width));

                    if (SystemVars.Platform == Platform.PSX)
                    { 
                        //linedoubling
                        destMem.Offset += Screen.SCREEN_WIDTH;
                        Array.ConstrainedCopy(srcMem.Data, srcMem.Offset, destMem.Data, destMem.Offset, _resMan.ReadUInt16(frHead.width));
                    }

                    srcMem.Offset += _resMan.ReadUInt16(frHead.width);
                    destMem.Offset += Screen.SCREEN_WIDTH;
                }

                _system.GraphicsManager.CopyRectToScreen(_screenBuf, destY * Screen.SCREEN_WIDTH + destX, Screen.SCREEN_WIDTH, destX, destY, _resMan.ReadUInt16(frHead.width), _resMan.ReadUInt16(frHead.height));
                _resMan.ResClose(SwordRes.SR_VLIGHT);
                destX += 32;
            }
        }
示例#31
0
        public void Draw()
        {
            FrameHeader fHead = new FrameHeader(_resMan.FetchFrame(_resMan.FetchRes(_resId), (uint)_frameIdx));
            ByteAccess src = new ByteAccess(fHead.Data.Data, fHead.Data.Offset + FrameHeader.Size);
            var dst = new ByteAccess(_dstBuf);

            if (SystemVars.Platform == Platform.PSX && _resId != 0)
            {
                var HIFbuf = new byte[_resMan.ReadUInt16(fHead.height) * _resMan.ReadUInt16(fHead.width)];
                Screen.DecompressHIF(src.Data, src.Offset, HIFbuf);
                src = new ByteAccess(HIFbuf);

                if (_resMan.ReadUInt16(fHead.width) < 300)
                    for (var cnt = 0; cnt < _resMan.ReadUInt16(fHead.height); cnt++)
                    {
                        for (var cntx = 0; cntx < _resMan.ReadUInt16(fHead.width); cntx++)
                            if (src[cntx] != 0)
                                dst[cntx] = src[cntx];

                        dst.Offset += Screen.SCREEN_WIDTH;
                        for (var cntx = 0; cntx < _resMan.ReadUInt16(fHead.width); cntx++)
                            if (src[cntx] != 0)
                                dst[cntx] = src[cntx];

                        dst.Offset += Screen.SCREEN_WIDTH;
                        src.Offset += _resMan.ReadUInt16(fHead.width);
                    }
                else if (_resId == SwordRes.SR_DEATHPANEL)
                { // Check for death panel psx version (which is 1/3 of original width)
                    for (var cnt = 0; cnt < _resMan.ReadUInt16(fHead.height) / 2; cnt++)
                    {
                        //Stretched panel is bigger than 640px, check we don't draw outside screen
                        for (var cntx = 0; (cntx < (_resMan.ReadUInt16(fHead.width)) / 3) && (cntx < (Screen.SCREEN_WIDTH - 3)); cntx++)
                            if (src[cntx] != 0)
                            {
                                dst[cntx * 3] = src[cntx];
                                dst[cntx * 3 + 1] = src[cntx];
                                dst[cntx * 3 + 2] = src[cntx];
                            }
                        dst.Offset += Screen.SCREEN_WIDTH;

                        for (var cntx = 0; cntx < (_resMan.ReadUInt16(fHead.width)) / 3; cntx++)
                            if (src[cntx] != 0)
                            {
                                dst[cntx * 3] = src[cntx];
                                dst[cntx * 3 + 1] = src[cntx];
                                dst[cntx * 3 + 2] = src[cntx];
                            }
                        dst.Offset += Screen.SCREEN_WIDTH;
                        src.Offset += _resMan.ReadUInt16(fHead.width) / 3;
                    }
                }
                else
                { //save slots needs to be multiplied by 2 in height
                    for (var cnt = 0; cnt < _resMan.ReadUInt16(fHead.height); cnt++)
                    {
                        for (var cntx = 0; cntx < _resMan.ReadUInt16(fHead.width) / 2; cntx++)
                            if (src[cntx] != 0)
                            {
                                dst[cntx * 2] = src[cntx];
                                dst[cntx * 2 + 1] = src[cntx];
                            }

                        dst.Offset += Screen.SCREEN_WIDTH;
                        for (var cntx = 0; cntx < _resMan.ReadUInt16(fHead.width) / 2; cntx++)
                            if (src[cntx] != 0)
                            {
                                dst[cntx * 2] = src[cntx];
                                dst[cntx * 2 + 1] = src[cntx];
                            }

                        dst.Offset += Screen.SCREEN_WIDTH;
                        src.Offset += _resMan.ReadUInt16(fHead.width) / 2;
                    }
                }
            }
            else
                for (var cnt = 0; cnt < _resMan.ReadUInt16(fHead.height); cnt++)
                {
                    for (var cntx = 0; cntx < _resMan.ReadUInt16(fHead.width); cntx++)
                        if (src[cntx] != 0)
                            dst[cntx] = src[cntx];

                    dst.Offset += Screen.SCREEN_WIDTH;
                    src.Offset += _resMan.ReadUInt16(fHead.width);
                }

            _system.GraphicsManager.CopyRectToScreen(_dstBuf.Data, _dstBuf.Offset, Screen.SCREEN_WIDTH, _x, _y, _width, _height);
        }
示例#32
0
        private void PerformPostProcessing(byte[] screen)
        {
            // TODO: We don't support displaying these in true color yet,
            // nor using the PSX fonts to display subtitles.
            if (SystemVars.Platform == Core.IO.Platform.PSX /* || _decoderType == kVideoDecoderMP2*/)
                return;

            if (_movieTexts.Count > 0)
            {
                if (_decoder.CurrentFrame == _movieTexts[0]._startFrame)
                {
                    var text = new ByteAccess(System.Text.Encoding.UTF8.GetBytes(_movieTexts[0]._text));
                    _textMan.MakeTextSprite(2, text, 600, Text.LetterCol);

                    var frame = new FrameHeader(_textMan.GiveSpriteData(2));
                    _textWidth = _resMan.ReadUInt16(frame.width);
                    _textHeight = _resMan.ReadUInt16(frame.height);
                    _textX = 320 - _textWidth / 2;
                    _textY = 420 - _textHeight;
                    _textColor = _movieTexts[0]._color;
                }
                if (_decoder.CurrentFrame == _movieTexts[0]._endFrame)
                {
                    _textMan.ReleaseText(2, false);
                    _movieTexts.RemoveAt(0);
                }
            }

            ByteAccess src, dst;
            int x, y;

            if (_textMan.GiveSpriteData(2) != null)
            {
                src = new ByteAccess(_textMan.GiveSpriteData(2));
                src.Offset += FrameHeader.Size;
                dst = new ByteAccess(screen, _textY * Screen.SCREEN_WIDTH + _textX * 1);

                for (y = 0; y < _textHeight; y++)
                {
                    for (x = 0; x < _textWidth; x++)
                    {
                        switch (src[x])
                        {
                            case Text.BorderCol:
                                dst[x] = (byte)GetBlackColor();
                                break;
                            case Text.LetterCol:
                                dst[x] = (byte)FindTextColor();
                                break;
                        }
                    }
                    src.Offset += _textWidth;
                    dst.Offset += Screen.SCREEN_WIDTH;
                }
            }
            else if (_textX != 0 && _textY != 0)
            {
                // If the frame doesn't cover the entire screen, we have to
                // erase the subtitles manually.

                int frameWidth = _decoder.GetWidth();
                int frameHeight = _decoder.GetHeight();
                int frameX = (_vm.Settings.Game.Width - frameWidth) / 2;
                int frameY = (_vm.Settings.Game.Height - frameHeight) / 2;

                dst = new ByteAccess(screen, _textY * _vm.Settings.Game.Width);

                for (y = 0; y < _textHeight; y++)
                {
                    if (_textY + y < frameY || _textY + y >= frameY + frameHeight)
                    {
                        dst.Data.Set(dst.Offset + _textX, (byte)GetBlackColor(), _textWidth);
                    }
                    else {
                        if (frameX > _textX)
                        {
                            dst.Data.Set(dst.Offset + _textX, (byte)GetBlackColor(), frameX - _textX);
                        }
                        if (frameX + frameWidth < _textX + _textWidth)
                        {
                            dst.Data.Set(dst.Offset + frameX + frameWidth, (byte)GetBlackColor(), _textX + _textWidth - (frameX + frameWidth));
                        }
                    }

                    dst.Offset += _vm.Settings.Game.Width;
                }

                _textX = 0;
                _textY = 0;
            }
        }
示例#33
0
        protected override void SetupPointers()
        {
            if (SystemVars.Instance.GameVersion.Version.Minor == 109)
            {
                // disk demo uses a different AdLib driver version, some offsets have changed
                //_musicDataLoc = (_musicData[0x11CC] << 8) | _musicData[0x11CB];
                //_initSequence = _musicData + 0xEC8;

                _musicDataLoc = _musicData.ToUInt16(0x1200);
                _initSequence = new ByteAccess(_musicData, 0xEFB);
            }
            else if (SystemVars.Instance.GameVersion.Version.Minor == 267)
            {
                _musicDataLoc = _musicData.ToUInt16(0x11F7);
                _initSequence = new ByteAccess(_musicData, 0xE87);
            }
            else
            {
                _musicDataLoc = _musicData.ToUInt16(0x1201);
                _initSequence = new ByteAccess(_musicData, 0xE91);
            }
            _nextMusicPoll = 0;
        }
示例#34
0
文件: Text.cs 项目: scemino/nscumm
        public void MakeTextSprite(byte slot, ByteAccess text, ushort maxWidth, byte pen)
        {
            var lines = new LineInfo[MaxLines];
            var numLines = AnalyzeSentence(text, maxWidth, lines);

            ushort sprWidth = 0;
            ushort lineCnt;
            for (lineCnt = 0; lineCnt < numLines; lineCnt++)
                if (lines[lineCnt].Width > sprWidth)
                    sprWidth = lines[lineCnt].Width;

            var sprHeight = (ushort)(_charHeight * numLines);
            var sprSize = (uint)(sprWidth * sprHeight);
            Debug.Assert(_textBlocks[slot] == null); // if this triggers, the speechDriver failed to call Text::releaseText.
            _textBlocks[slot] = new FrameHeader(new byte[sprSize + FrameHeader.Size]);

            Array.Copy(new[] { (byte)'N', (byte)'u', (byte)' ', (byte)' ' }, 0, _textBlocks[slot].runTimeComp.Data, _textBlocks[slot].runTimeComp.Offset, 4);
            _textBlocks[slot].compSize = 0;
            _textBlocks[slot].width = _resMan.ReadUInt16(sprWidth);
            _textBlocks[slot].height = _resMan.ReadUInt16(sprHeight);
            _textBlocks[slot].offsetX = 0;
            _textBlocks[slot].offsetY = 0;

            var linePtr = new ByteAccess(_textBlocks[slot].Data.Data, _textBlocks[slot].Data.Offset + FrameHeader.Size);
            linePtr.Data.Set(linePtr.Offset, NoCol, (int)sprSize);
            for (lineCnt = 0; lineCnt < numLines; lineCnt++)
            {
                var sprPtr = (sprWidth - lines[lineCnt].Width) / 2; // center the text
                for (ushort pos = 0; pos < lines[lineCnt].Length; pos++)
                {
                    sprPtr += CopyChar(text[0], new ByteAccess(linePtr.Data, linePtr.Offset + sprPtr), sprWidth, pen) - Overlap;
                    text.Offset++;
                }
                text.Offset++; // skip space at the end of the line
                if (SystemVars.Platform == Platform.PSX) //Chars are half height in psx version
                    linePtr.Offset += _charHeight / 2 * sprWidth;
                else
                    linePtr.Offset += _charHeight * sprWidth;
            }
        }
示例#35
0
 public void LoadLiveList(UShortAccess src)
 {
     for (var cnt = 0; cnt < TOTAL_SECTIONS; cnt++)
     {
         if (_liveList[cnt] != 0)
         {
             _resMan.ResClose(_objectList[cnt]);
             _cptData[cnt] = null;
         }
         _liveList[cnt] = src[cnt];
         if (_liveList[cnt] != 0)
             _cptData[cnt] = new ByteAccess(_resMan.CptResOpen(_objectList[cnt]), Header.Size);
     }
 }
示例#36
0
文件: Screen.cs 项目: scemino/nscumm
        private void VerticalMask(ushort x, ushort y, ushort bWidth, ushort bHeight)
        {
            if (SwordRes.RoomDefTable[_currentScreen].totalLayers <= 1)
                return;

            if (SystemVars.Platform == Platform.PSX)
            { // PSX sprites are vertical shrinked, and some width shrinked
                bHeight *= 2;
                bWidth *= 2;
            }

            bWidth = (ushort)((bWidth + (x & (SCRNGRID_X - 1)) + (SCRNGRID_X - 1)) / SCRNGRID_X);
            bHeight = (ushort)((bHeight + (y & (SCRNGRID_Y - 1)) + (SCRNGRID_Y - 1)) / SCRNGRID_Y);

            x /= SCRNGRID_X;
            y /= SCRNGRID_Y;
            if (x + bWidth > _gridSizeX)
                bWidth = (ushort)(_gridSizeX - x);
            if (y + bHeight > _gridSizeY)
                bHeight = (ushort)(_gridSizeY - y);

            ushort gridY = (ushort)(y + SCREEN_TOP_EDGE / SCRNGRID_Y); // imaginary screen on top
            gridY = (ushort)(gridY + bHeight - 1); // we start from the bottom edge
            ushort gridX = (ushort)(x + SCREEN_LEFT_EDGE / SCRNGRID_X); // imaginary screen left
            ushort lGridSizeX = (ushort)(_gridSizeX + 2 * (SCREEN_LEFT_EDGE / SCRNGRID_X)); // width of the grid for the imaginary screen

            for (ushort blkx = 0; blkx < bWidth; blkx++)
            {
                // A sprite can be masked by several layers at the same time,
                // so we have to check them all. See bug #917427.
                for (short level = (short)(SwordRes.RoomDefTable[_currentScreen].totalLayers - 2); level >= 0; level--)
                {
                    if (_layerGrid[level][gridX + blkx + gridY * lGridSizeX] != 0)
                    {
                        var grid = new UShortAccess(_layerGrid[level].Data, _layerGrid[level].Offset + (gridX + blkx + gridY * lGridSizeX) * 2);
                        for (short blky = (short)(bHeight - 1); blky >= 0; blky--)
                        {
                            if (grid[0] != 0)
                            {
                                ByteAccess blkData;
                                if (SystemVars.Platform == Platform.PSX)
                                    blkData = new ByteAccess(_layerBlocks[level + 1].Data, _layerBlocks[level + 1].Offset + (_resMan.ReadUInt16(grid[0]) - 1) * 64); //PSX layers are half height too...
                                else
                                    blkData = new ByteAccess(_layerBlocks[level + 1].Data, _layerBlocks[level + 1].Offset + (_resMan.ReadUInt16(grid[0]) - 1) * 128);
                                BlitBlockClear((ushort)(x + blkx), (ushort)(y + blky), blkData);
                            }
                            else
                                break;
                            grid.Offset -= lGridSizeX * 2;
                        }
                    }
                }
            }
        }
示例#37
0
文件: Mouse.cs 项目: scemino/nscumm
 public MousePtr(byte[] data)
 {
     Data = data;
     Offset = 0;
     dummyData = new ByteAccess(data, Offset + 10);
 }
示例#38
0
文件: Control.cs 项目: scemino/nscumm
        public void DoRestore()
        {
            var bufPos = new ByteAccess(_restoreBuf);
            _objMan.LoadLiveList(new UShortAccess(_restoreBuf));
            bufPos.Offset += ObjectMan.TOTAL_SECTIONS * 2;
            for (var cnt = 0; cnt < Logic.NUM_SCRIPT_VARS; cnt++)
            {
                Logic.ScriptVars[cnt] = bufPos.Data.ToUInt32(bufPos.Offset);
                bufPos.Offset += 4;
            }
            uint playerSize = (SwordObject.Size - 12000) / 4;
            var cpt = _objMan.FetchObject(Logic.PLAYER);
            var playerRaw = new UIntAccess(cpt.Data, cpt.Offset);

            for (var cnt2 = 0; cnt2 < playerSize; cnt2++)
            {
                playerRaw[0] = bufPos.Data.ToUInt32(bufPos.Offset);
                playerRaw.Offset += 4;
                bufPos.Offset += 4;
            }

            Logic.ScriptVars[(int)ScriptVariableNames.CHANGE_DIR] = (uint)cpt.dir;
            Logic.ScriptVars[(int)ScriptVariableNames.CHANGE_X] = (uint)cpt.xcoord;
            Logic.ScriptVars[(int)ScriptVariableNames.CHANGE_Y] = (uint)cpt.ycoord;
            Logic.ScriptVars[(int)ScriptVariableNames.CHANGE_STANCE] = StaticRes.STAND;
            Logic.ScriptVars[(int)ScriptVariableNames.CHANGE_PLACE] = (uint)cpt.place;
            SystemVars.JustRestoredGame = 1;
            if (SystemVars.IsDemo)
                Logic.ScriptVars[(int)ScriptVariableNames.PLAYINGDEMO] = 1;
        }