Esempio n. 1
0
        internal virtual void SetCameraFollows(Actor actor, bool setCamera = false)
        {
            _camera.Mode = CameraMode.FollowActor;
            _camera.ActorToFollow = actor.Number;

            if (!actor.IsInCurrentRoom)
            {
                StartScene(actor.Room);
                _camera.Mode = CameraMode.FollowActor;
                _camera.CurrentPosition.X = actor.Position.X;
                SetCameraAt(new Point(_camera.CurrentPosition.X, 0));
            }

            int t = actor.Position.X / 8 - _screenStartStrip;

            if (t < _camera.LeftTrigger || t > _camera.RightTrigger || setCamera)
                SetCameraAt(new Point(actor.Position.X, 0));

            for (int i = 1; i < Actors.Length; i++)
            {
                if (Actors[i].IsInCurrentRoom)
                    Actors[i].NeedRedraw = true;
            }
            RunInventoryScript(0);
        }
Esempio n. 2
0
        void InitActors()
        {
            int numActors;

            if (Game.Version == 8)
            {
                numActors = 80;
            }
            else if (Game.Version == 7 || Game.GameId == GameId.SamNMax)
            {
                numActors = 30;
            }
            else if (Game.GameId == GameId.Maniac)
            {
                numActors = 25;
            }
            else
            {
                numActors = 13;
            }

            Actors = new Actor[numActors];
            for (byte i = 0; i < Actors.Length; i++)
            {
                if (Game.Version == 0)
                {
                    Actors[i] = new Actor0(this, i);
                }
                else if (Game.Version <= 2)
                {
                    Actors[i] = new Actor2(this, i);
                }
                else if (Game.Version == 3)
                {
                    Actors[i] = new Actor3(this, i);
                }
                else
                {
                    Actors[i] = new Actor(this, i);
                }
                Actors[i].Init(-1);

                // this is from IDB
                if ((_game.Version <= 1) || (Game.GameId == GameId.Maniac && (Game.Features.HasFlag(GameFeatures.Demo))))
                    Actors[i].SetActorCostume(i);
            }

            if (Game.GameId == GameId.Maniac && Game.Version <= 1)
            {
                ResetV1ActorTalkColor();
            }
        }
Esempio n. 3
0
        internal override void SetCameraFollows(Actor a, bool setCamera = false)
        {
            var oldfollow = Camera.ActorToFollow;

            Camera.ActorToFollow = a.Number;
            Variables[VariableCameraFollowedActor.Value] = a.Number;

            if (!a.IsInCurrentRoom)
            {
                StartScene(a.Room);
            }

            var ax = Math.Abs(a.Position.X - Camera.CurrentPosition.X);
            var ay = Math.Abs(a.Position.Y - Camera.CurrentPosition.Y);

            if (ax > Variables[VariableCameraThresholdX.Value] || ay > Variables[VariableCameraThresholdY.Value] || ax > (ScreenWidth / 2) || ay > (ScreenHeight / 2))
            {
                SetCameraAt(a.Position);
            }

            if (a.Number != oldfollow)
                RunInventoryScript(0);
        }
Esempio n. 4
0
        internal byte WalkboxFindTarget(Actor a, int destbox, Point walkdest)
        {
            var actor = (Actor0)a;

            byte nextBox = (byte)GetNextBox(a.Walkbox, (byte)destbox);

            if (nextBox != 0xFF && nextBox == destbox && AreBoxesNeighbors(a.Walkbox, nextBox))
            {
                actor.NewWalkTo = walkdest;
                return nextBox;
            }

            if (nextBox != 0xFF && nextBox != a.Walkbox)
            {
                Point p;
                ScummMath.GetClosestPtOnBox(GetBoxCoordinates(nextBox), a.Position, out p);
                actor.NewWalkTo = p;
            }
            else
            {
                if (walkdest.X == -1)
                    actor.NewWalkTo = actor.CurrentWalkTo;
                else
                    actor.NewWalkTo = walkdest;
            }
            return nextBox;
        }
Esempio n. 5
0
        internal bool HandleNextCharsetCode(Actor a, ref int code)
        {
            int color, frme, c = 0, oldy;
            bool endLoop = false;

            var bufferPos = _charsetBufPos;
            while (!endLoop)
            {
                c = _charsetBuffer[bufferPos++];
                if (!(c == 0xFF || (Game.Version <= 6 && c == 0xFE)))
                {
                    break;
                }
                c = _charsetBuffer[bufferPos++];

                if (NewLineCharacter != 0 && c == NewLineCharacter)
                {
                    c = 13;
                    break;
                }

                switch (c)
                {
                    case 1:
                        c = 13; // new line
                        endLoop = true;
                        break;

                    case 2:
                        _haveMsg = 0;
                        _keepText = true;
                        endLoop = true;
                        break;

                    case 3:
                        _haveMsg = (_game.Version >= 7) ? 1 : 0xFF;
                        _keepText = false;
                        endLoop = true;
                        break;

                    case 8:
					// Ignore this code here. Occurs e.g. in MI2 when you
					// talk to the carpenter on scabb island. It works like
					// code 1 (=newline) in verb texts, but is ignored in
					// spoken text (i.e. here). Used for very long verb
					// sentences.
                        break;

                    case 9:
                        frme = _charsetBuffer[bufferPos] | (_charsetBuffer[bufferPos + 1] << 8);
                        bufferPos += 2;
                        if (a != null)
                            a.StartAnimActor(frme);
                        break;

                    case 10:
					// Note the similarity to the code in debugMessage()
                        {
                            var talkSound_a = (_charsetBuffer[bufferPos] | (_charsetBuffer[bufferPos + 1] << 8) | (_charsetBuffer[bufferPos + 4] << 16) | (_charsetBuffer[bufferPos + 5] << 24));
                            var talkSound_b = (_charsetBuffer[bufferPos + 8] | (_charsetBuffer[bufferPos + 9] << 8) | (_charsetBuffer[bufferPos + 12] << 16) | (_charsetBuffer[bufferPos + 13] << 24));
                            bufferPos += 14;
                            Sound.TalkSound(talkSound_a, talkSound_b, 2);
                            _haveActorSpeechMsg = false;
                        }
                        break;

                    case 12:
                        color = _charsetBuffer[bufferPos] | (_charsetBuffer[bufferPos + 1] << 8);
                        bufferPos += 2;
                        if (color == 0xFF)
                            _charset.SetColor(_charsetColor);
                        else
                            _charset.SetColor((byte)color);
                        break;

                    case 13:
					//debug(0, "handleNextCharsetCode: Unknown opcode 13 %d", READ_LE_UINT16(buffer));
                        bufferPos += 2;
                        break;

                    case 14:
                        oldy = _charset.GetFontHeight();
                        _charset.SetCurID(_charsetBuffer[bufferPos++]);
                        bufferPos += 2;
                        Array.Copy(_charsetData[_charset.GetCurId()], CharsetColorMap, 4);
                        _nextTop -= _charset.GetFontHeight() - oldy;
                        break;

                    default:
                        throw new NotSupportedException(string.Format("handleNextCharsetCode: invalid code {0}", c));
                }
            }
            _charsetBufPos = bufferPos;
            code = c;
            return (c != 2 && c != 3);
        }
Esempio n. 6
0
        internal void StartScene(byte room, Actor a = null, int objectNr = 0)
        {
            StopTalk();

            FadeOut(_switchRoomEffect2);
            _newEffect = _switchRoomEffect;

            if (CurrentScript != 0xFF)
            {
                if (_slots[CurrentScript].Where == WhereIsObject.Room || _slots[CurrentScript].Where == WhereIsObject.FLObject)
                {
                    //nukeArrays(CurrentScript);
                    CurrentScript = 0xFF;
                }
                else if (_slots[CurrentScript].Where == WhereIsObject.Local)
                {
                    //if (slots[CurrentScript].cutsceneOverride && _game.version >= 5)
                    //    error("Script %d stopped with active cutscene/override in exit", slots[CurrentScript].number);

                    //nukeArrays(CurrentScript);
                    CurrentScript = 0xFF;
                }
            }

            if (VariableNewRoom.HasValue)
                _variables[VariableNewRoom.Value] = room;

            RunExitScript();

            KillScriptsAndResources();

            if (_game.Version >= 4)
            {
                StopCycle(0);
            }

            for (var i = 1; i < Actors.Length; i++)
            {
                Actors[i].Hide();
            }

            if (Game.Version >= 7)
            {
                // Set the shadow palette(s) to all black. This fixes
                // bug #795940, and actually makes some sense (after all,
                // shadows tend to be rather black, don't they? ;-)
                Array.Clear(_shadowPalette, 0, _shadowPalette.Length);
            }
            else
            {
                for (var i = 0; i < 256; i++)
                {
                    Gdi.RoomPalette[i] = (byte)i;
                    if (_shadowPalette != null)
                        _shadowPalette[i] = (byte)i;
                }

                if (Game.Version < 5)
                {
                    SetDirtyColors(0, 255);
                }
            }

            Variables[VariableRoom.Value] = room;
            _fullRedraw = true;

            _currentRoom = room;

            if (room >= 0x80 && Game.Version < 7)
                _roomResource = _resourceMapper[room & 0x7F];
            else
                _roomResource = room;

            if (VariableRoomResource.HasValue)
                Variables[VariableRoomResource.Value] = _roomResource;

            if (room != 0)
                ResourceManager.LoadRoom(room);

            if (room != 0 && _game.Version == 5 && room == _roomResource)
                Variables[VariableRoomFlag.Value] = 1;

            ClearRoomObjects();

            if (_currentRoom == 0)
            {
                if (roomData != null)
                {
                    _ignoreEntryExitScript = true;
                    roomData.ExitScript.Data = new byte[0];
                    //roomData.Objects.Clear();
                }
                return;
            }

            roomData = _resManager.GetRoom(_roomResource);
            _ignoreEntryExitScript = false;
            if (roomData.HasPalette)
            {
                SetCurrentPalette(0);
            }

            Gdi.NumZBuffer = GetNumZBuffers();

            Gdi.TransparentColor = roomData.TransparentColor;
            ResetRoomSubBlocks();
            ResetRoomObjects();
            _drawingObjects.Clear();

            if (Game.Version >= 7)
            {
                // Resize main virtual screen in V7 games. This is necessary
                // because in V7, rooms may be higher than one screen, so we have
                // to accomodate for that.
                _mainVirtScreen = new VirtScreen(MainVirtScreen.TopLine, ScreenWidth, roomData.Header.Height - MainVirtScreen.TopLine, MainVirtScreen.PixelFormat, 2, true);
            }
            Gdi.SetMaskHeight(roomData.Header.Height);

            if (VariableRoomWidth.HasValue && VariableRoomHeight.HasValue)
            {
                Variables[VariableRoomWidth.Value] = roomData.Header.Width;
                Variables[VariableRoomHeight.Value] = roomData.Header.Height;
            }

            if (VariableCameraMinX.HasValue)
            {
                _variables[VariableCameraMinX.Value] = ScreenWidth / 2;
            }
            if (VariableCameraMaxX.HasValue)
            {
                _variables[VariableCameraMaxX.Value] = roomData.Header.Width - (ScreenWidth / 2);
            }

            if (Game.Version >= 7)
            {
                Variables[VariableCameraMinY.Value] = ScreenHeight / 2;
                Variables[VariableCameraMaxY.Value] = roomData.Header.Height - (ScreenHeight / 2);
                SetCameraAt(new Point((ScreenWidth / 2), (ScreenHeight / 2)));
            }
            else
            {
                _camera.Mode = CameraMode.Normal;
                _camera.CurrentPosition.X = _camera.DestinationPosition.X = (ScreenWidth / 2);
                _camera.CurrentPosition.Y = _camera.DestinationPosition.Y = (ScreenHeight / 2);
            }

            if (_roomResource == 0)
                return;

            Gdi.ClearGfxUsageBits();

            if (_game.Version >= 5 && a != null)
            {
                var where = GetWhereIsObject(objectNr);
                if (where != WhereIsObject.Room && where != WhereIsObject.FLObject)
                    throw new NotSupportedException(string.Format("StartScene: Object {0} is not in room {1}", objectNr, _currentRoom));

                Point pos;
                int dir;
                GetObjectXYPos(objectNr, out pos, out dir);
                a.PutActor(pos, _currentRoom);
                a.SetDirection(dir + 180);
                a.StopActorMoving();

                if (Game.GameId == Scumm.IO.GameId.SamNMax)
                {
                    Camera.CurrentPosition.X = Camera.DestinationPosition.X = a.Position.X;
                    SetCameraAt(a.Position);
                }
            }

            ShowActors();

            EgoPositioned = false;

            TownsResetPalCycleFields();

            RunEntryScript();

            if (Game.Version >= 1 && Game.Version <= 2)
            {
                RunScript(5, false, false, new int[0]);
            }
            else if ((Game.Version >= 5) && (Game.Version <= 6))
            {
                if (a != null && !EgoPositioned)
                {
                    var pos = GetObjectXYPos(objectNr);
                    a.PutActor(pos, _currentRoom);
                    a.Moving = 0;
                }
            }
            else if (_game.Version >= 7)
            {
                if (Camera.ActorToFollow != 0)
                {
                    a = Actors[Camera.ActorToFollow];
                    SetCameraAt(a.Position);
                }
            }

            _doEffect = true;

            // Hint the backend about the virtual keyboard during copy protection screens
            if (_game.GameId == GameId.Monkey2)
            {
                if (room == 108)
                    _inputManager.ShowVirtualKeyboard();
                else
                    _inputManager.HideVirtualKeyboard();
            }
            else if (_game.GameId == GameId.Monkey1 && _game.Variant == "ega")
            {   // this is my estimation that the room code is 90 (untested)
                if (room == 90)
                    _inputManager.ShowVirtualKeyboard();
                else
                    _inputManager.HideVirtualKeyboard();
            }
        }