예제 #1
0
파일: AutoRoute.cs 프로젝트: scemino/nscumm
        public ushort DoAutoRoute(Compact cpt)
        {
            var cptScreen = (byte)cpt.Core.screen;
            var cptWidth = (byte)SkyCompact.GetMegaSet(cpt).gridWidth;
            InitWalkGrid(cptScreen, cptWidth);

            byte startX, startY, destX, destY;
            short initStaX, initStaY, initDestX, initDestY;

            ClipCoordX(cpt.Core.xcood, out startX, out initStaX);
            ClipCoordY(cpt.Core.ycood, out startY, out initStaY);
            ClipCoordX(cpt.Core.arTargetX, out destX, out initDestX);
            ClipCoordY(cpt.Core.arTargetY, out destY, out initDestY);

            var raw = _skyCompact.FetchCptRaw(cpt.Core.animScratchId);
            Array.Clear(raw, 0, 64);
            var routeDest = new UShortAccess(raw, 0);
            if ((startX == destX) && (startY == destY))
                return 2;

            var routeGrid = new UShortAccess(_routeGrid, 0);
            if (routeGrid[(destY + 1) * RouteGridWidth + destX + 1] != 0)
            {
                //if ((cpt == &Sky::SkyCompact::foster) && (cptScreen == 12) && (destX == 2) && (destY == 14)) {
                if (_skyCompact.CptIsId(cpt, (ushort)CptIds.Foster) && (cptScreen == 12) && (destX == 2) &&
                    (destY == 14))
                {
                    /* workaround for Scriptbug #1043047
                       In screen 12 (the pipe factory) Joey can block Foster's target
                       coordinates (2/14). This is normally not too tragic, but in the
                       scene when foster gets thrown out by Lamb (first time you enter
                       the pipe factory), the game would enter an infinite loop. */
                    routeGrid[(destY + 1) * RouteGridWidth + destX + 1] = 0;
                    // hide this part joey from the grid
                }
                else
                    return 1; // AR destination is an unaccessible block
            }

            if (!CalcWalkGrid(startX, startY, destX, destY))
                return 1; // can't find route to block

            var routeData = MakeRouteData(destX, destY);
            // the route is done.
            // if there was an initial x movement (due to clipping) tag it onto the start
            routeData = CheckInitMove(routeData, initStaX);

            byte cnt = 0;
            do
            {
                routeDest[cnt] = routeData[cnt];
                routeDest[cnt + 1] = routeData[cnt + 1];
                cnt += 2;
            } while (routeData[cnt - 2] != 0);
            return 0;
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
0
파일: Debug.cs 프로젝트: scemino/nscumm
 public void Script(uint command, UShortAccess scriptData)
 {
     Write("SCRIPT: {0}", Opcodes[command]);
     if (command == 0 || command == 6)
         Write(" {0}", ScriptVars[scriptData[0] / 4]);
     else
     {
         for (var i = 0; i < OpcodeParameter[command]; i++)
         {
             Write(" {0}", scriptData[i]);
         }
     }
     Write(" ");  // Print an empty line as separator
 }
예제 #5
0
        private void ArTurn()
        {
            var turnData = new UShortAccess(_skyCompact.FetchCptRaw(_compact.Core.turnProgId), _compact.Core.turnProgPos * 2);
            _compact.Core.frame = turnData[0];
            turnData.Offset += 2;
            _compact.Core.turnProgPos++;

            if (turnData[0] == 0)
            { // turn done?
              // Back to ar mode
                _compact.Core.arAnimIndex = 0;
                _compact.Core.logic = L_AR_ANIM;
            }
        }
예제 #6
0
        private void Turn()
        {
            var turnData = new UShortAccess(_skyCompact.FetchCptRaw(_compact.Core.turnProgId), _compact.Core.turnProgPos * 2);
            if (turnData[0] != 0)
            {
                _compact.Core.frame = turnData[0];
                _compact.Core.turnProgPos++;
                return;
            }

            // turn_to_script:
            _compact.Core.arAnimIndex = 0;
            _compact.Core.logic = L_SCRIPT;

            LogicScript();
        }
예제 #7
0
 private bool FnMoveItems(uint listNo, uint screenNo, uint c)
 {
     // Move a list of id's to another screen
     var p = new UShortAccess(_skyCompact.FetchCptRaw((ushort)CptIds.MoveList), 0);
     p = new UShortAccess(_skyCompact.FetchCptRaw(p[(int)listNo]), 0);
     for (int i = 0; i < 2; i++)
     {
         if (p.Value == 0)
             return true;
         Compact cpt = _skyCompact.FetchCpt(p.Value); p.Offset += 2;
         cpt.Core.screen = (ushort)(screenNo & 0xffff);
     }
     return true;
 }
예제 #8
0
파일: Screen.cs 프로젝트: scemino/nscumm
        private void SortSprites()
        {
            var sortList = new StSortList[30];
            int currDrawList = Logic.DRAW_LIST_NO;

            while (Logic.ScriptVariables[currDrawList] != 0)
            {
                // big_sort_loop
                uint spriteCnt = 0;
                var loadDrawList = Logic.ScriptVariables[currDrawList];
                currDrawList++;

                bool nextDrawList;
                do
                {
                    // a_new_draw_list:
                    var drawListData = new UShortAccess(_skyCompact.FetchCptRaw((ushort)loadDrawList), 0);
                    nextDrawList = false;
                    while (!nextDrawList && (drawListData[0] != 0))
                    {
                        if (drawListData[0] == 0xFFFF)
                        {
                            loadDrawList = drawListData[1];
                            nextDrawList = true;
                        }
                        else
                        {
                            // process_this_id:
                            var spriteComp = _skyCompact.FetchCpt(drawListData[0]);
                            if (((spriteComp.Core.status & 4) != 0) && // is it sortable playfield?(!?!)
                                (spriteComp.Core.screen == Logic.ScriptVariables[Logic.SCREEN]))
                            {
                                // on current screen
                                var spriteData = SkyEngine.ItemList[spriteComp.Core.frame >> 6];
                                if (spriteData == null)
                                {
                                    // TODO: debug(9, "Missing file %d", spriteComp.frame >> 6);
                                    spriteComp.Core.status = 0;
                                }
                                else
                                {
                                    sortList[spriteCnt].YCood =
                                        (uint)
                                            (spriteComp.Core.ycood + spriteData.ToUInt16(18) + spriteData.ToUInt16(8));
                                    sortList[spriteCnt].Compact = spriteComp;
                                    sortList[spriteCnt].Sprite = spriteData;
                                    spriteCnt++;
                                }
                            }
                            drawListData.Offset += 2;
                        }
                    }
                } while (nextDrawList);
                // made_list:
                if (spriteCnt > 1)
                {
                    // bubble sort
                    for (var cnt1 = 0; cnt1 < spriteCnt - 1; cnt1++)
                        for (var cnt2 = cnt1 + 1; cnt2 < spriteCnt; cnt2++)
                            if (sortList[cnt1].YCood > sortList[cnt2].YCood)
                            {
                                StSortList tmp;
                                tmp.YCood = sortList[cnt1].YCood;
                                tmp.Sprite = sortList[cnt1].Sprite;
                                tmp.Compact = sortList[cnt1].Compact;
                                sortList[cnt1].YCood = sortList[cnt2].YCood;
                                sortList[cnt1].Sprite = sortList[cnt2].Sprite;
                                sortList[cnt1].Compact = sortList[cnt2].Compact;
                                sortList[cnt2].YCood = tmp.YCood;
                                sortList[cnt2].Sprite = tmp.Sprite;
                                sortList[cnt2].Compact = tmp.Compact;
                            }
                }
                for (var cnt = 0; cnt < spriteCnt; cnt++)
                {
                    DrawSprite(sortList[cnt].Sprite, sortList[cnt].Compact);
                    if ((sortList[cnt].Compact.Core.status & 8) != 0)
                        VectorToGame(0x81);
                    else
                        VectorToGame(1);
                    if ((sortList[cnt].Compact.Core.status & 0x200) == 0)
                        VerticalMask();
                }
            }
        }
예제 #9
0
파일: Control.cs 프로젝트: scemino/nscumm
        void SaveThumbnail(BinaryWriter output, Surface thumb)
        {
            var bpp = Surface.GetBytesPerPixel(thumb.PixelFormat);
            if (bpp != 2 && bpp != 4)
            {
                // TODO: warning("trying to save thumbnail with bpp %u", bpp);
                return;
            }

            ThumbnailHeader header = new ThumbnailHeader();
            header.Type = ScummHelper.MakeTag('T', 'H', 'M', 'B');
            header.Size = (uint)(ThumbnailHeaderSize + thumb.Width * thumb.Height * bpp);
            header.Version = THMB_VERSION;
            header.Width = (ushort)thumb.Width;
            header.Height = (ushort)thumb.Height;

            output.WriteUInt32BigEndian(header.Type);
            output.WriteUInt32BigEndian(header.Size);
            output.WriteByte(header.Version);
            output.WriteUInt16BigEndian(header.Width);
            output.WriteUInt16BigEndian(header.Height);

            // Serialize the PixelFormat
            output.WriteByte(bpp);
            output.WriteByte(3);
            output.WriteByte(2);
            output.WriteByte(3);
            output.WriteByte(8);
            output.WriteByte(11);
            output.WriteByte(5);
            output.WriteByte(0);
            output.WriteByte(0);

            // Serialize the pixel data
            for (uint y = 0; y < thumb.Height; ++y)
            {
                switch (bpp)
                {
                    case 2:
                        {
                            var pixels = new UShortAccess(thumb.Pixels, (int)(y * thumb.Width * 2));
                            for (uint x = 0; x < thumb.Width; ++x)
                            {
                                output.WriteUInt16BigEndian(pixels[0]);
                                pixels.Offset += 2;
                            }
                        }
                        break;

                    case 4:
                        {
                            var pixels = new UIntAccess(thumb.Pixels, (int)(y * thumb.Width * 4));
                            for (var x = 0; x < thumb.Width; ++x)
                            {
                                output.WriteUInt32BigEndian(pixels[0]);
                                pixels.Offset += 4;
                            }
                        }
                        break;

                    default:
                        throw new NotSupportedException();
                }
            }
        }
예제 #10
0
파일: AutoRoute.cs 프로젝트: scemino/nscumm
        private UShortAccess MakeRouteData(byte destX, byte destY)
        {
            Array.Clear(_routeBuf, 0, _routeBuf.Length);
            var routeBuf = new UShortAccess(_routeBuf, 0);
            var routeGrid = new UShortAccess(_routeGrid, 0);

            var routePos = (destY + 1) * RouteGridWidth + destX + 1;
            var dataTrg = (Logic.ROUTE_SPACE >> 1) - 2;

            var lastVal = (ushort)(routeGrid[routePos] - 1);
            while (lastVal != 0)
            {
                // lastVal == 0 means route is done.
                dataTrg -= 2;

                short walkDirection = 0;
                for (byte cnt = 0; cnt < 4; cnt++)
                    if (lastVal == routeGrid[routePos + RouteDirections[cnt]])
                    {
                        routeBuf[dataTrg + 1] = LogicCommands[cnt];
                        walkDirection = RouteDirections[cnt];
                        break;
                    }

                if (walkDirection == 0)
                    throw new InvalidOperationException(
                        string.Format("makeRouteData:: can't find way through walkGrid (pos {0})", lastVal));

                while (lastVal != 0 && (lastVal == routeGrid[routePos + walkDirection]))
                {
                    routeBuf[dataTrg] += WalkJump;
                    lastVal--;
                    routePos += walkDirection;
                }
            }
            return new UShortAccess(routeBuf.Data, routeBuf.Offset + dataTrg * 2);
        }
예제 #11
0
파일: AutoRoute.cs 프로젝트: scemino/nscumm
        private void InitWalkGrid(byte screen, byte width)
        {
            byte stretch = 0;
            var screenGrid = _grid.GiveGrid(screen);
            var screenGridPos = Logic.GRID_SIZE;
            var wGridPos = new UShortAccess(_routeGrid, ((RouteGridSize >> 1) - RouteGridWidth - 2) * 2);

            Array.Clear(_routeGrid, 0, _routeGrid.Length);
            byte bitsLeft = 0;
            uint gridData = 0;
            for (byte gridCntY = 0; gridCntY < RouteGridHeight - 2; gridCntY++)
            {
                for (byte gridCntX = 0; gridCntX < RouteGridWidth - 2; gridCntX++)
                {
                    if (bitsLeft == 0)
                    {
                        screenGridPos -= 4;
                        gridData = screenGrid.ToUInt32(screenGridPos);
                        bitsLeft = 32;
                    }
                    if ((gridData & 1) != 0)
                    {
                        wGridPos[0] = 0xFFFF; // block is not accessible
                        stretch = width;
                    }
                    else if (stretch != 0)
                    {
                        wGridPos[0] = 0xFFFF;
                        stretch--;
                    }
                    wGridPos.Offset -= 2;
                    bitsLeft--;
                    gridData >>= 1;
                }
                wGridPos.Offset -= 4;
                stretch = 0;
            }
        }
예제 #12
0
파일: Mouse.cs 프로젝트: scemino/nscumm
        private void PointerEngine(ushort xPos, ushort yPos)
        {
            UShortAccess currentList;
            var currentListNum = Logic.ScriptVariables[Logic.MOUSE_LIST_NO];
            do
            {
                currentList = new UShortAccess(_skyCompact.FetchCptRaw((ushort)currentListNum), 0);
                while ((currentList[0] != 0) && (currentList[0] != 0xFFFF))
                {
                    var itemNum = currentList[0];
                    var itemData = _skyCompact.FetchCpt(itemNum);
                    currentList.Offset += 2;
                    if ((itemData.Core.screen == Logic.ScriptVariables[Logic.SCREEN]) &&
                        ((itemData.Core.status & 16) != 0))
                    {
                        if (itemData.Core.xcood + itemData.Core.mouseRelX > xPos) continue;
                        if (itemData.Core.xcood + itemData.Core.mouseRelX + itemData.Core.mouseSizeX < xPos) continue;
                        if (itemData.Core.ycood + itemData.Core.mouseRelY > yPos) continue;
                        if (itemData.Core.ycood + itemData.Core.mouseRelY + itemData.Core.mouseSizeY < yPos) continue;
                        // we've hit the item
                        if (Logic.ScriptVariables[Logic.SPECIAL_ITEM] == itemNum)
                            return;
                        Logic.ScriptVariables[Logic.SPECIAL_ITEM] = itemNum;
                        if (Logic.ScriptVariables[Logic.GET_OFF] != 0)
                            Logic.MouseScript(Logic.ScriptVariables[Logic.GET_OFF], itemData);
                        Logic.ScriptVariables[Logic.GET_OFF] = itemData.Core.mouseOff;
                        if (itemData.Core.mouseOn != 0)
                            Logic.MouseScript(itemData.Core.mouseOn, itemData);
                        return;
                    }
                }
                if (currentList[0] == 0xFFFF)
                    currentListNum = currentList[1];
            } while (currentList[0] != 0);

            if (Logic.ScriptVariables[Logic.SPECIAL_ITEM] != 0)
            {
                Logic.ScriptVariables[Logic.SPECIAL_ITEM] = 0;

                if (Logic.ScriptVariables[Logic.GET_OFF] != 0)
                    Logic.Script((ushort)Logic.ScriptVariables[Logic.GET_OFF], (ushort)(Logic.ScriptVariables[Logic.GET_OFF] >> 16));
                Logic.ScriptVariables[Logic.GET_OFF] = 0;
            }
        }
예제 #13
0
파일: Text.cs 프로젝트: scemino/nscumm
 public void FnTextModule(uint textInfoId, uint textNo)
 {
     FnSetFont(1);
     var msgData = new UShortAccess(_skyCompact.FetchCptRaw((ushort)textInfoId), 0);
     var textId = LowTextManager(textNo, msgData[1], msgData[2], 209, false);
     Logic.ScriptVariables[Logic.RESULT] = textId.CompactNum;
     var textCompact = _skyCompact.FetchCpt(textId.CompactNum);
     textCompact.Core.xcood = msgData[3];
     textCompact.Core.ycood = msgData[4];
     FnSetFont(0);
 }
예제 #14
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;
        }
예제 #15
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;
                        }
                    }
                }
            }
        }
예제 #16
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
 }
예제 #17
0
파일: Screen.cs 프로젝트: scemino/nscumm
        private void VerticalMask()
        {
            if (_sprWidth == 0)
                return;
            var startGridOfs = (int)((_sprY + _sprHeight - 1) * GridX + _sprX);
            var startScreenPtr = (int)((_sprY + _sprHeight - 1) * GridH * GameScreenWidth + _sprX * GridW);

            for (uint layerCnt = Logic.LAYER_1_ID; layerCnt <= Logic.LAYER_3_ID; layerCnt++)
            {
                var gridOfs = startGridOfs;
                var screenPtr = startScreenPtr;
                for (uint widCnt = 0; widCnt < _sprWidth; widCnt++)
                {
                    // x_loop
                    var nLayerCnt = layerCnt;
                    while (Logic.ScriptVariables[(int) (nLayerCnt + 3)] != 0)
                    {
                        var scrGrid = new UShortAccess(SkyEngine.ItemList[Logic.ScriptVariables[(int) (layerCnt + 3)]], 0);
                        if (scrGrid[gridOfs] != 0)
                        {
                            VertMaskSub(scrGrid, gridOfs, screenPtr, layerCnt);
                            break;
                        }
                        nLayerCnt++;
                    }
                    // next_x:
                    screenPtr += GridW;
                    gridOfs++;
                }
            }
        }
예제 #18
0
파일: Screen.cs 프로젝트: scemino/nscumm
        private void DoSprites(byte layer)
        {
            ushort drawListNum = Logic.DRAW_LIST_NO;
            while (Logic.ScriptVariables[drawListNum] != 0)
            {
                // std sp loop
                var idNum = Logic.ScriptVariables[drawListNum];
                drawListNum++;

                var drawList = new UShortAccess(_skyCompact.FetchCptRaw((ushort)idNum), 0);
                while (drawList[0] != 0)
                {
                    // new_draw_list:
                    while ((drawList[0] != 0) && (drawList[0] != 0xFFFF))
                    {
                        // back_loop:
                        // not_new_list
                        var spriteData = _skyCompact.FetchCpt(drawList[0]);
                        drawList.Offset += 2;
                        if (((spriteData.Core.status & (1 << layer)) != 0) &&
                            (spriteData.Core.screen == Logic.ScriptVariables[Logic.SCREEN]))
                        {
                            var toBeDrawn = SkyEngine.ItemList[spriteData.Core.frame >> 6];
                            if (toBeDrawn == null)
                            {
                                // TODO: debug(9, "Spritedata %d not loaded", spriteData.frame >> 6);
                                spriteData.Core.status = 0;
                            }
                            else
                            {
                                DrawSprite(toBeDrawn, spriteData);
                                if (layer == Back)
                                    VerticalMask();
                                if ((spriteData.Core.status & 8) != 0)
                                    VectorToGame(0x81);
                                else
                                    VectorToGame(1);
                            }
                        }
                    }
                    while (drawList[0] == 0xFFFF)
                        drawList = new UShortAccess(_skyCompact.FetchCptRaw(drawList[1]), 0);
                }
            }
        }
예제 #19
0
        private void ArAnim()
        {
            // Follow a route
            // Mega should be in getToMode

            // only check collisions on character boundaries
            if (((_compact.Core.xcood & 7) != 0) || ((_compact.Core.ycood & 7) != 0))
            {
                MainAnim();
                return;
            }

            // On character boundary. Have we been told to wait?
            // if not - are WE colliding?

            if (_compact.Core.waitingFor == 0xffff)
            { // 1st cycle of re-route does not require collision checks
                MainAnim();
                return;
            }

            if (_compact.Core.waitingFor != 0)
            {
                // ok, we've been told we've hit someone
                // we will wait until we are no longer colliding
                // with them. here we check to see if we are (still) colliding.
                // if we are then run the stop script. if not clear the flag
                // and continue.

                // remember - this could be the first ar cycle for some time,
                // we might have been told to wait months ago. if we are
                // waiting for one person then another hits us then
                // c_waiting_for will be replaced by the new mega - this is
                // fine because the later collision will almost certainly
                // take longer to clear than the earlier one.

                if (Collide(_skyCompact.FetchCpt(_compact.Core.waitingFor)))
                {
                    StopAndWait();
                    return;
                }

                // we are not in fact hitting this person so clr & continue
                // it must have registered some time ago

                _compact.Core.waitingFor = 0; // clear id flag
            }

            // ok, our turn to check for collisions

            var logicList = new UShortAccess(_skyCompact.FetchCptRaw((ushort)_scriptVariables[LOGIC_LIST_NO]), 0);
            ushort id;

            while ((id = logicList[0]) != 0)
            { // get an id

                logicList.Offset += 2;
                if (id == 0xffff)
                { // address change?
                    logicList = new UShortAccess(_skyCompact.FetchCptRaw(logicList[0]), 0); // get new logic list
                    continue;
                }

                if (id == (ushort)(_scriptVariables[CUR_ID] & 0xffff)) // is it us?
                    continue;

                _scriptVariables[HIT_ID] = id; // save target id for any possible c_mini_bump
                var cpt = _skyCompact.FetchCpt(id);

                if ((cpt.Core.status & (1 << ST_COLLISION_BIT)) == 0) // can it collide?
                    continue;

                if (cpt.Core.screen != _compact.Core.screen) // is it on our screen?
                    continue;

                if (Collide(cpt))
                { // check for a hit
                  // ok, we've hit a mega
                  // is it moving... or something else?

                    if (cpt.Core.logic != L_AR_ANIM)
                    { // check for following route
                      // it is doing something else
                      // we restart our get-to script
                      // first tell it to wait for us - in case it starts moving
                      // ( *it may have already hit us and stopped to wait )

                        _compact.Core.waitingFor = 0xffff; // effect 1 cycle collision skip
                                                           // tell it it is waiting for us
                        cpt.Core.waitingFor = (ushort)(_scriptVariables[CUR_ID] & 0xffff);
                        // restart current script
                        SkyCompact.GetSub(_compact, _compact.Core.mode + 2).Field = 0;
                        _compact.Core.logic = L_SCRIPT;
                        LogicScript();
                        return;
                    }

                    Script(_compact.Core.miniBump, 0);
                    return;
                }
            }

            // ok, there was no collisions
            // now check for interaction request
            // *note: the interaction is always set up as an action script

            if (_compact.Core.request != 0)
            {
                _compact.Core.mode = C_ACTION_MODE; // put into action mode
                _compact.Core.actionSub = _compact.Core.request;
                _compact.Core.actionSub_off = 0;
                _compact.Core.request = 0; // trash request
                _compact.Core.logic = L_SCRIPT;
                LogicScript();
                return;
            }

            // any flag? - or any change?
            // if change then re-run the current script, which must be
            // a position independent get-to		 ----

            if (_compact.Core.atWatch == 0)
            { // any flag set?
                MainAnim();
                return;
            }

            // ok, there is an at watch - see if it's changed

            if (_compact.Core.atWas == _scriptVariables[_compact.Core.atWatch / 4])
            { // still the same?
                MainAnim();
                return;
            }

            // changed so restart the current script
            // *not suitable for base initiated ARing
            SkyCompact.GetSub(_compact, _compact.Core.mode + 2).Field = 0;

            _compact.Core.logic = L_SCRIPT;
            LogicScript();
        }
예제 #20
0
파일: AutoRoute.cs 프로젝트: scemino/nscumm
        private static ushort CheckBlock(byte[] block, int blockPos)
        {
            var b = new UShortAccess(block, blockPos);
            ushort retVal = 0xFFFF;

            for (byte cnt = 0; cnt < 4; cnt++)
            {
                var fieldVal = b[RouteDirections[cnt]];
                if (fieldVal != 0 && (fieldVal < retVal))
                    retVal = fieldVal;
            }
            return retVal;
        }
예제 #21
0
        private bool FnTestList(uint id, uint x, uint y)
        {
            _scriptVariables[RESULT] = 0; // assume fail
            var list = new UShortAccess(_skyCompact.FetchCptRaw((ushort)id), 0);

            while (list.Value != 0)
            {
                if ((x >= list[0]) && (x < list[1]) && (y >= list[2]) && (y < list[3]))
                    _scriptVariables[RESULT] = list[4];
                list.Offset += 5 * 2;
            }
            return true;
        }
예제 #22
0
파일: AutoRoute.cs 프로젝트: scemino/nscumm
        private bool CalcWalkGrid(byte startX, byte startY, byte destX, byte destY)
        {
            short directionX, directionY;
            byte roiX, roiY; // Rectangle Of Interest in the walk grid
            if (startY > destY)
            {
                directionY = -RouteGridWidth;
                roiY = startY;
            }
            else
            {
                directionY = RouteGridWidth;
                roiY = (byte)(RouteGridHeight - 1 - startY);
            }
            if (startX > destX)
            {
                directionX = -1;
                roiX = (byte)(startX + 2);
            }
            else
            {
                directionX = 1;
                roiX = (byte)(RouteGridWidth - 1 - startX);
            }

            var walkDest = (destY + 1) * RouteGridWidth + destX + 1;
            var walkStart = (startY + 1) * RouteGridWidth + startX + 1;

            var routeGrid = new UShortAccess(_routeGrid, 0);
            routeGrid[walkStart] = 1;

            // if we are on the edge, move diagonally from start
            if (roiY < RouteGridHeight - 3)
                walkStart -= directionY;

            if (roiX < RouteGridWidth - 2)
                walkStart -= directionX;

            var gridChanged = true;
            var foundRoute = false;

            while (!foundRoute && gridChanged)
            {
                gridChanged = false;
                var yWalkCalc = walkStart;
                for (byte cnty = 0; cnty < roiY; cnty++)
                {
                    var xWalkCalc = yWalkCalc;
                    for (byte cntx = 0; cntx < roiX; cntx++)
                    {
                        if (routeGrid[xWalkCalc] == 0)
                        {
                            // block wasn't done, yet
                            var blockRet = CheckBlock(_routeGrid, routeGrid.Offset + xWalkCalc * 2);
                            if (blockRet < 0xFFFF)
                            {
                                routeGrid[xWalkCalc] = (ushort)(blockRet + 1);
                                gridChanged = true;
                            }
                        }
                        xWalkCalc += directionX;
                    }
                    yWalkCalc += directionY;
                }
                if (routeGrid[walkDest] != 0)
                {
                    // okay, finished
                    foundRoute = true;
                }
                else
                {
                    // we couldn't find the route, let's extend the ROI
                    if (roiY < RouteGridHeight - 4)
                    {
                        walkStart -= directionY;
                        roiY++;
                    }
                    if (roiX < RouteGridWidth - 4)
                    {
                        walkStart -= directionX;
                        roiX++;
                    }
                }
            }
            return foundRoute;
        }
예제 #23
0
파일: Sound.cs 프로젝트: scemino/nscumm
        private double EndiannessHeuristicValue(UShortAccess data, uint dataSize, ref uint maxSamples)
        {
            if (data == null)
                return 50000; // the heuristic value for the wrong endianess is about 21000 (1/3rd of the 16 bits range)

            double diff_sum = 0;
            uint cpt = 0;
            short prev_value = (short)data[0];
            for (int i = 1; i < dataSize && cpt < maxSamples; ++i)
            {
                short value = (short)data[i];
                if (value != prev_value)
                {
                    diff_sum += Math.Abs((double)(value - prev_value));
                    ++cpt;
                    prev_value = value;
                }
            }
            if (cpt == 0)
                return 50000;
            maxSamples = cpt;
            return diff_sum / cpt;
        }
예제 #24
0
파일: AutoRoute.cs 프로젝트: scemino/nscumm
 private static UShortAccess CheckInitMove(UShortAccess data, short initStaX)
 {
     var index = 0;
     if (initStaX < 0)
     {
         index -= 2;
         data[index + 1] = Logic.RIGHTY;
         data[index] = (ushort)((-initStaX + 7) & 0xFFF8);
     }
     else if (initStaX > 0)
     {
         index -= 2;
         data[index] = (ushort)((initStaX + 7) & 0xFFF8);
         data[index] = (ushort)((initStaX + 7) & 0xFFF8);
     }
     return new UShortAccess(data.Data, data.Offset + index * 2);
 }
예제 #25
0
파일: Sound.cs 프로젝트: scemino/nscumm
 private void CalcWaveVolume(UShortAccess data, int length)
 {
     var blkPos = new UShortAccess(data.Data, data.Offset + 918 * 2);
     uint cnt;
     for (cnt = 0; cnt < WAVE_VOL_TAB_LENGTH; cnt++)
         _waveVolume[cnt] = false;
     _waveVolPos = 0;
     for (uint blkCnt = 1; blkCnt < length / 918; blkCnt++)
     {
         if (blkCnt >= WAVE_VOL_TAB_LENGTH)
         {
             // TODO: warning("Wave vol tab too small");
             return;
         }
         int average = 0;
         for (cnt = 0; cnt < 918; cnt++)
             average += blkPos[(int)cnt];
         average /= 918;
         uint diff = 0;
         for (cnt = 0; cnt < 918; cnt++)
         {
             short smpDiff = (short)(blkPos[0] - average);
             diff += (uint)Math.Abs(smpDiff);
             blkPos.Offset += 2;
         }
         if (diff > WAVE_VOL_THRESHOLD)
             _waveVolume[blkCnt - 1] = true;
     }
 }
예제 #26
0
        private bool FnEyeball(uint id, uint b, uint c)
        {
            // set 'result' to frame no. pointing to foster, according to table used
            // eg. FN_eyeball (id_eye_90_table);

            var eyeTable = new UShortAccess(_skyCompact.FetchCptRaw((ushort)id), 0);
            Compact cpt = _skyCompact.FetchCpt(ID_BLUE_FOSTER);

            int x = cpt.Core.xcood; // 168 < x < 416
            x -= 168;
            x >>= 3;

            int y = cpt.Core.ycood; // 256 < y < 296
            y -= 256;
            y <<= 2;

            _scriptVariables[RESULT] = (uint)(eyeTable[x + y] + S91);
            return true;
        }
예제 #27
0
파일: Control.cs 프로젝트: scemino/nscumm
        public bool RestoreGameFromFile(byte slot)
        {

            ushort cnt;
            var fName = $"sword1.{slot:D3}";
            using (var inf = new BinaryReader(_saveFileMan.OpenForLoading(fName)))
            {
                // TODO:
                //if (inf==null)
                //{
                //    // Display an error message, and do nothing
                //    // TODO: DisplayMessage(0, "Can't open file '%s'. (%s)", fName, _saveFileMan.popErrorDesc().c_str());
                //    return false;
                //}

                uint saveHeader = inf.ReadUInt32();
                if (saveHeader != SAVEGAME_HEADER)
                {
                    // Display an error message, and do nothing
                    // TODO: DisplayMessage(0, "Save game '%s' is corrupt", fName);
                    return false;
                }

                inf.BaseStream.Seek(40, SeekOrigin.Current); // skip description
                byte saveVersion = inf.ReadByte();

                if (saveVersion > SAVEGAME_VERSION)
                {
                    // TODO: warning("Different save game version");
                    return false;
                }

                if (saveVersion < 2) // These older version of the savegames used a flag to signal presence of thumbnail
                    inf.BaseStream.Seek(1, SeekOrigin.Current);

                SkipThumbnail(inf);

                inf.ReadUInt32BigEndian(); // save date
                inf.ReadUInt16BigEndian(); // save time

                if (saveVersion < 2)
                {
                    // Before version 2 we didn't had play time feature
                    // TODO: g_engine.setTotalPlayTime(0);
                }
                else
                {
                    var time = inf.ReadUInt32BigEndian();
                    // TODO: g_engine.setTotalPlayTime(time * 1000);
                }

                _restoreBuf = new byte[
                    ObjectMan.TOTAL_SECTIONS * 2 +
                    Logic.NUM_SCRIPT_VARS * 4 +
                    (SwordObject.Size - 12000)];

                var liveBuf = new UShortAccess(_restoreBuf);
                var scriptBuf = new UIntAccess(_restoreBuf, 2 * ObjectMan.TOTAL_SECTIONS);
                var playerBuf = new UIntAccess(_restoreBuf, 2 * ObjectMan.TOTAL_SECTIONS + 4 * Logic.NUM_SCRIPT_VARS);

                for (cnt = 0; cnt < ObjectMan.TOTAL_SECTIONS; cnt++)
                    liveBuf[cnt] = inf.ReadUInt16();

                for (cnt = 0; cnt < Logic.NUM_SCRIPT_VARS; cnt++)
                    scriptBuf[cnt] = inf.ReadUInt32();

                uint playerSize = (SwordObject.Size - 12000) / 4;
                for (var cnt2 = 0; cnt2 < playerSize; cnt2++)
                    playerBuf[cnt2] = inf.ReadUInt32();

                // TODO: error
                //if (inf.err() || inf.eos())
                //{
                //    displayMessage(0, "Can't read from file '%s'. (%s)", fName, _saveFileMan.popErrorDesc().c_str());
                //    delete inf;
                //    free(_restoreBuf);
                //    _restoreBuf = NULL;
                //    return false;
                //}
            }

            return true;
        }
예제 #28
0
파일: Sound.cs 프로젝트: scemino/nscumm
        private UShortAccess UncompressSpeech(uint index, uint cSize, out uint size)
        {
            _cowFile.BaseStream.Seek(index, SeekOrigin.Begin);
            var fBuf = _cowFile.ReadBytes((int)cSize);
            uint headerPos = 0;

            while ((fBuf.ToUInt32BigEndian((int)headerPos) != ScummHelper.MakeTag('d', 'a', 't', 'a')) && (headerPos < 100))
                headerPos++;

            UShortAccess srcData;
            if (headerPos < 100)
            {
                int resSize;
                uint srcPos;
                short length;
                cSize /= 2;
                headerPos += 4; // skip 'data' tag
                if (_cowMode != CowMode.CowDemo)
                {
                    resSize = (int)(fBuf.ToUInt32((int)headerPos) >> 1);
                    headerPos += 4;
                }
                else
                {
                    // the demo speech files have the uncompressed size
                    // embedded in the compressed stream *sigh*
                    //
                    // But not always, apparently. See bug #2182450. Is
                    // there any way to figure out the size other than
                    // decoding the sound in that case?

                    if (fBuf[headerPos + 1] == 0)
                    {
                        if (fBuf.ToInt16((int)headerPos) == 1)
                        {
                            resSize = fBuf.ToInt16((int)(headerPos + 2));
                            resSize |= fBuf.ToInt16((int)(headerPos + 6)) << 16;
                        }
                        else
                            resSize = fBuf.ToInt32((int)(headerPos + 2));
                        resSize >>= 1;
                    }
                    else
                    {
                        resSize = 0;
                        srcData = new UShortAccess(fBuf);
                        srcPos = headerPos >> 1;
                        while (srcPos < cSize)
                        {
                            length = (short)srcData[(int)srcPos];
                            srcPos++;
                            if (length < 0)
                            {
                                resSize -= length;
                                srcPos++;
                            }
                            else
                            {
                                resSize += length;
                                srcPos = (uint)(srcPos + length);
                            }
                        }
                    }
                }
                Debug.Assert((headerPos & 1) == 0);
                srcData = new UShortAccess(fBuf);
                srcPos = headerPos >> 1;
                uint dstPos = 0;
                var dstData = new UShortAccess(new byte[resSize * 2]);
                int samplesLeft = resSize;
                while (srcPos < cSize && samplesLeft > 0)
                {
                    length = (short)(_bigEndianSpeech ? ScummHelper.SwapBytes(srcData[(int)srcPos]) : srcData[(int)srcPos]);
                    srcPos++;
                    if (length < 0)
                    {
                        length = (short)-length;
                        if (length > samplesLeft)
                            length = (short)samplesLeft;
                        short value;
                        if (_bigEndianSpeech)
                        {
                            value = (short)ScummHelper.SwapBytes(srcData[(int)srcPos]);
                        }
                        else
                        {
                            value = (short)srcData[(int)srcPos];
                        }
                        for (ushort cnt = 0; cnt < (ushort)length; cnt++)
                            dstData[(int)dstPos++] = (ushort)value;
                        srcPos++;
                    }
                    else
                    {
                        if (length > samplesLeft)
                            length = (short)samplesLeft;
                        if (_bigEndianSpeech)
                        {
                            for (ushort cnt = 0; cnt < length; cnt++)
                                dstData[(int)dstPos++] = ScummHelper.SwapBytes(srcData[(int)srcPos++]);
                        }
                        else
                        {
                            Array.Copy(srcData.Data, (int)(srcData.Offset + srcPos * 2), dstData.Data, (int)(dstData.Offset + dstPos * 2), length * 2);
                            dstPos = (uint)(dstPos + length);
                            srcPos = (uint)(srcPos + length);
                        }
                    }
                    samplesLeft -= length;
                }
                if (samplesLeft > 0)
                {
                    dstData.Data.Set((int)(dstData.Offset + dstPos), 0, samplesLeft * 2);
                }
                if (_cowMode == CowMode.CowDemo) // demo has wave output size embedded in the compressed data
                {
                    dstData.Data.WriteUInt32(dstData.Offset, 0);
                }
                size = (uint)(resSize * 2);
                CalcWaveVolume(dstData, resSize);
                return dstData;
            }
            else
            {
                // TODO: warning("Sound::uncompressSpeech(): DATA tag not found in wave header");
                size = 0;
                return null;
            }
        }
예제 #29
0
        private bool FnGetTo(uint targetPlaceId, uint mode, uint c)
        {
            _compact.Core.upFlag = (ushort)mode; // save mode for action script
            _compact.Core.mode += 4; // next level up
            Compact cpt = _skyCompact.FetchCpt(_compact.Core.place);
            if (cpt == null)
            {
                // TODO: warning("can't find _compact's getToTable. Place compact is NULL");
                return false;
            }
            var raw = _skyCompact.FetchCptRaw(cpt.Core.getToTableId);
            if (raw == null)
            {
                //TODO:  warning("Place compact's getToTable is NULL");
                return false;
            }

            var getToTable = new UShortAccess(raw, 0);
            while (getToTable.Value != targetPlaceId)
                getToTable.Offset += 4;

            // get new script
            SkyCompact.GetSub(_compact, _compact.Core.mode).Field = getToTable[1];
            SkyCompact.GetSub(_compact, (ushort)(_compact.Core.mode + 2)).Field = 0;

            return false; // drop out of script
        }
예제 #30
0
파일: ObjectMan.cs 프로젝트: scemino/nscumm
 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);
     }
 }
예제 #31
0
        private bool FnResetId(uint id, uint resetBlock, uint c)
        {
            // used when a mega is to be restarted
            // eg - when a smaller mega turn to larger
            // - a mega changes rooms...

            var cpt = _skyCompact.FetchCpt((ushort)id);
            var rst = new UShortAccess(_skyCompact.FetchCptRaw((ushort)resetBlock), 0);

            if (cpt == null)
            {
                // TODO: warning("fnResetId(): Compact %d (id) == NULL", id);
                return true;
            }

            if (rst == null)
            {
                // TODO: warning("fnResetId(): Compact %d (resetBlock) == NULL", resetBlock);
                return true;
            }

            ushort off;
            while ((off = rst[0]) != 0xffff)
            {
                rst.Offset += 2;
                _skyCompact.GetCompactElem(cpt, off).Field = rst[0];
                rst.Offset += 2;
            }
            return true;
        }