⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xvm.cpp

📁 < Game Script Mastery>> source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:

                            if ( ResolveOpPntr ( 0 ) == ResolveOpPntr ( 1 ) )
                                break;

                            // Copy the source operand into the destination

                            CopyValue ( & Dest, Source );

                            break;

                        // The arithmetic instructions only work with destination types that
                        // are either integers or floats. They first check for integers and
                        // assume that anything else is a float. Mod only works with integers.

                        // Add

                        case INSTR_ADD:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral += ResolveOpAsInt ( 1 );
                            else
                                Dest.fFloatLiteral += ResolveOpAsFloat ( 1 );

                            break;

                        // Subtract

                        case INSTR_SUB:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral -= ResolveOpAsInt ( 1 );
                            else
                                Dest.fFloatLiteral -= ResolveOpAsFloat ( 1 );

                            break;

                        // Multiply

                        case INSTR_MUL:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral *= ResolveOpAsInt ( 1 );
                            else
                                Dest.fFloatLiteral *= ResolveOpAsFloat ( 1 );

                            break;

                        // Divide

                        case INSTR_DIV:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral /= ResolveOpAsInt ( 1 );
                            else
                                Dest.fFloatLiteral /= ResolveOpAsFloat ( 1 );

                            break;

                        // Modulus

                        case INSTR_MOD:

                            // Remember, Mod works with integers only

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral %= ResolveOpAsInt ( 1 );

                            break;

                        // Exponentiate

                        case INSTR_EXP:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral = ( int ) pow ( Dest.iIntLiteral, ResolveOpAsInt ( 1 ) );
                            else
                                Dest.fFloatLiteral = ( float ) pow ( Dest.fFloatLiteral, ResolveOpAsFloat ( 1 ) );

                            break;

                        // The bitwise instructions only work with integers. They do nothing
                        // when the destination data type is anything else.

                        // And

                        case INSTR_AND:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral &= ResolveOpAsInt ( 1 );

                             break;

                        // Or

                        case INSTR_OR:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral |= ResolveOpAsInt ( 1 );

                            break;

                        // Exclusive Or

                        case INSTR_XOR:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral ^= ResolveOpAsInt ( 1 );

                            break;

                        // Shift Left

                        case INSTR_SHL:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral <<= ResolveOpAsInt ( 1 );

                            break;

                        // Shift Right

                        case INSTR_SHR:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral >>= ResolveOpAsInt ( 1 );

                            break;
                    }

                    // Use ResolveOpPntr () to get a pointer to the destination Value structure and
                    // move the result there

					* ResolveOpPntr ( 0 ) = Dest;

					break;
                }

                // ---- Unary Operations

                // These instructions work much like the binary operations in the sense that
                // they only work with integers and floats (except Not, which works with
                // integers only). Any other destination data type will be ignored.

                case INSTR_NEG:
                case INSTR_NOT:
                case INSTR_INC:
                case INSTR_DEC:
                {
                    // Get the destination type (operand index 0)

                    int iDestStoreType = GetOpType ( 0 );

                    // Get a local copy of the destination itself

                    Value Dest = ResolveOpValue ( 0 );

                    switch ( iOpcode )
                    {
                        // Negate

                        case INSTR_NEG:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral = -Dest.iIntLiteral;
                            else
                                Dest.fFloatLiteral = -Dest.fFloatLiteral;

                            break;

                        // Not

                        case INSTR_NOT:

                            if ( Dest.iType == OP_TYPE_INT )
                                Dest.iIntLiteral = ~ Dest.iIntLiteral;

                            break;

                        // Increment

                        case INSTR_INC:

                            if ( Dest.iType == OP_TYPE_INT )
                                ++ Dest.iIntLiteral;
                            else
                                ++ Dest.fFloatLiteral;

                            break;

                        // Decrement

                        case INSTR_DEC:

                            if ( Dest.iType == OP_TYPE_INT )
                                -- Dest.iIntLiteral;
                            else
                                -- Dest.fFloatLiteral;

                            break;
                    }

                    // Move the result to the destination

                    * ResolveOpPntr ( 0 ) = Dest;

					break;
                }

                // ---- String Processing

                case INSTR_CONCAT:
                {
                    // Get a local copy of the destination operand (operand index 0)

                    Value Dest = ResolveOpValue ( 0 );

                    // Get a local copy of the source string (operand index 1)

                    char * pstrSourceString = ResolveOpAsString ( 1 );

                    // If the destination isn't a string, do nothing

                    if ( Dest.iType != OP_TYPE_STRING )
                        break;

                    // Determine the length of the new string and allocate space for it (with a
                    // null terminator)

                    int iNewStringLength = strlen ( Dest.pstrStringLiteral ) + strlen ( pstrSourceString );
                    char * pstrNewString = ( char * ) malloc ( iNewStringLength + 1 );

                    // Copy the old string to the new one

                    strcpy ( pstrNewString, Dest.pstrStringLiteral );

                    // Concatenate the destination with the source

                    strcat ( pstrNewString, pstrSourceString );

                    // Free the existing string in the destination structure and replace it
                    // with the new string

                    free ( Dest.pstrStringLiteral );
                    Dest.pstrStringLiteral = pstrNewString;

                    // Copy the concatenated string pointer to its destination

                    * ResolveOpPntr ( 0 ) = Dest;

					break;
                }

				case INSTR_GETCHAR:
                {
                    // Get a local copy of the destination operand (operand index 0)

                    Value Dest = ResolveOpValue ( 0 );

                    // Get a local copy of the source string (operand index 1)

                    char * pstrSourceString = ResolveOpAsString ( 1 );

                    // Find out whether or not the destination is already a string

                    char * pstrNewString;
                    if ( Dest.iType == OP_TYPE_STRING )
                    {
                        // If it is, we can use it's existing string buffer as long as it's at
                        // least 1 character

                        if ( strlen ( Dest.pstrStringLiteral ) >= 1 )
                        {
                            pstrNewString = Dest.pstrStringLiteral;
                        }
                        else
                        {
                            free ( Dest.pstrStringLiteral );
                            pstrNewString = ( char * ) malloc ( 2 );
                        }
                    }
                    else
                    {
                        // Otherwise allocate a new string and set the type

                        pstrNewString = ( char * ) malloc ( 2 );
                        Dest.iType = OP_TYPE_STRING;
                    }

                    // Get the index of the character (operand index 2)

                    int iSourceIndex = ResolveOpAsInt ( 2 );

                    // Copy the character and append a null-terminator

                    pstrNewString [ 0 ] = pstrSourceString [ iSourceIndex ];
                    pstrNewString [ 1 ] = '\0';

                    // Set the string pointer in the destination Value structure

                    Dest.pstrStringLiteral = pstrNewString;

                    // Copy the concatenated string pointer to its destination

                    * ResolveOpPntr ( 0 ) = Dest;

					break;
                }

				case INSTR_SETCHAR:
                {
                    // Get the destination index (operand index 1)

                    int iDestIndex = ResolveOpAsInt ( 1 );

                    // If the destination isn't a string, do nothing

                    if ( ResolveOpType ( 0 ) != OP_TYPE_STRING )
                        break;

                    // Get the source character (operand index 2)

                    char * pstrSourceString = ResolveOpAsString ( 2 );

                    // Set the specified character in the destination (operand index 0)

                    ResolveOpPntr ( 0 )->pstrStringLiteral [ iDestIndex ] = pstrSourceString [ 0 ];

					break;
                }

                // ---- Conditional Branching

				case INSTR_JMP:
                {
                    // Get the index of the target instruction (opcode index 0)

                    int iTargetIndex = ResolveOpAsInstrIndex ( 0 );

                    // Move the instruction pointer to the target

                    g_Scripts [ g_iCurrThread ].InstrStream.iCurrInstr = iTargetIndex;

                    break;
                }

				case INSTR_JE:
				case INSTR_JNE:
				case INSTR_JG:
				case INSTR_JL:
  				case INSTR_JGE:
				case INSTR_JLE:
                {
                    // Get the two operands

                    Value Op0 = ResolveOpValue ( 0 );
                    Value Op1 = ResolveOpValue ( 1 );

                    // Get the index of the target instruction (opcode index 2)

                    int iTargetIndex = ResolveOpAsInstrIndex ( 2 );

                    // Perform the specified comparison and jump if it evaluates to true

                    int iJump = FALSE;

                    switch ( iOpcode )
                    {
                        // Jump if Equal

                        case INSTR_JE:
                        {
                            switch ( Op0.iType )
                            {
                                case OP_TYPE_INT:
                                    if ( Op0.iIntLiteral == Op1.iIntLiteral )
                                        iJump = TRUE;
                                    break;

                                case OP_TYPE_FLOAT:
                                    if ( Op0.fFloatLiteral == Op1.fFloatLiteral )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -