Example #1
0
        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));
        }
Example #2
0
        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
        }
Example #3
0
        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;
                }
            }
        }
Example #4
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);
         }
     }
 }
Example #5
0
        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);
        }
Example #6
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;
        }
Example #7
0
 public MousePtr(byte[] data)
 {
     Data      = data;
     Offset    = 0;
     dummyData = new ByteAccess(data, Offset + 10);
 }
Example #8
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;
            }
        }
Example #9
0
 public ByteAccess(ByteAccess data)
     : this(data.Data, data.Offset)
 {
 }
Example #10
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);
        }