2015-02-15 18:53:04 +03:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2005-2009 Anchorite (TeamX), <anchorite2001@yandex.ru>
|
2015-02-15 21:33:27 +03:00
|
|
|
* Copyright (c) 2014-2015 Nirran, phobos2077
|
|
|
|
|
* Copyright (c) 2015 alexeevdv <mail@alexeevdv.ru>
|
2015-02-15 18:53:04 +03:00
|
|
|
* Distributed under the GNU GPL v3. For full terms see the file license.txt
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// C++ standard includes
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
// int2ssl includes
|
2015-02-13 16:59:11 +03:00
|
|
|
#include "Opcode.h"
|
|
|
|
|
#include "Utility.h"
|
|
|
|
|
|
2015-02-15 18:53:04 +03:00
|
|
|
// Third party includes
|
2015-02-13 16:59:11 +03:00
|
|
|
|
|
|
|
|
extern int g_nFalloutVersion;
|
|
|
|
|
|
|
|
|
|
COpcode::COpcode() :
|
2015-02-14 13:39:47 +03:00
|
|
|
m_wOperator(O_NOOP),
|
|
|
|
|
m_ulArgument(0)
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
COpcode::COpcode(const COpcode& opcode) :
|
2015-02-14 13:39:47 +03:00
|
|
|
m_wOperator(opcode.m_wOperator),
|
|
|
|
|
m_ulArgument(opcode.m_ulArgument)
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
COpcode::~COpcode()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
COpcode& COpcode::operator = (const COpcode& opcode)
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
m_wOperator = opcode.m_wOperator;
|
|
|
|
|
m_ulArgument = opcode.m_ulArgument;
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 13:39:47 +03:00
|
|
|
return (*this);
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void COpcode::Serialize(CArchive& ar)
|
|
|
|
|
{
|
2015-02-14 14:38:14 +03:00
|
|
|
if (ReadMSBWord(ar, m_wOperator) != OPERATOR_SIZE)
|
|
|
|
|
{
|
|
|
|
|
printf("Error: Unable read opcode\n");
|
2015-02-15 19:14:18 +03:00
|
|
|
throw std::exception();
|
2015-02-14 14:38:14 +03:00
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
if ((m_wOperator < O_OPERATOR) ||
|
|
|
|
|
((m_wOperator >= O_END_OP) &&
|
|
|
|
|
(m_wOperator != O_STRINGOP) &&
|
|
|
|
|
(m_wOperator != O_FLOATOP)&&
|
|
|
|
|
(m_wOperator != O_INTOP)))
|
|
|
|
|
{
|
|
|
|
|
ar.Flush();
|
|
|
|
|
printf("Error: Invalid opcode at 0x%08x\n", ar.GetFile()->GetPosition() - 2);
|
2015-02-15 19:14:18 +03:00
|
|
|
throw std::exception();
|
2015-02-14 14:38:14 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP))
|
|
|
|
|
{
|
|
|
|
|
if (ReadMSBULong(ar, m_ulArgument) != ARGUMENT_SIZE)
|
|
|
|
|
{
|
|
|
|
|
printf("Error: Unable read opcode argument\n");
|
2015-02-15 19:14:18 +03:00
|
|
|
throw std::exception();
|
2015-02-14 13:39:47 +03:00
|
|
|
}
|
2015-02-14 14:38:14 +03:00
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
2015-02-15 18:28:27 +03:00
|
|
|
void COpcode::Expect(CArchive& ar, uint16_t wOperator, bool bArgumentFound, uint32_t ulArgument)
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
Serialize(ar);
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
if (m_wOperator != wOperator)
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
printf("Error: Unexpected opcode (0x%04X expected, but 0x%04X found)\n", wOperator, m_wOperator);
|
2015-02-15 19:14:18 +03:00
|
|
|
throw std::exception();
|
2015-02-14 13:39:47 +03:00
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
if (bArgumentFound && ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP)))
|
|
|
|
|
{
|
|
|
|
|
if (m_ulArgument != ulArgument)
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
printf("Error: Unexpected argument of opcode. (0x%08X expected, but 0x%08X found)\n", ulArgument, m_ulArgument);
|
2015-02-15 19:14:18 +03:00
|
|
|
throw std::exception();
|
2015-02-14 13:39:47 +03:00
|
|
|
}
|
|
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
2015-02-15 18:10:01 +03:00
|
|
|
void COpcode::Expect(CArchive& ar, int nCount, uint16_t pwOperators[])
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
Serialize(ar);
|
2015-02-15 16:59:52 +03:00
|
|
|
bool bFound = false;
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
for(int i = 0; i < nCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (m_wOperator == pwOperators[i])
|
|
|
|
|
{
|
2015-02-15 16:59:52 +03:00
|
|
|
bFound = true;
|
2015-02-14 13:39:47 +03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
if (!bFound)
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
printf("Error: Unexpected opcode (");
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
for(int i = 0; i < nCount; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i != 0)
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
printf(" or ");
|
|
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 13:39:47 +03:00
|
|
|
printf("0x%04X", pwOperators[i]);
|
|
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 13:39:47 +03:00
|
|
|
printf(" expected, but 0x%04X found)\n", m_wOperator);
|
2015-02-15 19:14:18 +03:00
|
|
|
throw std::exception();
|
2015-02-14 13:39:47 +03:00
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
2015-02-15 16:59:52 +03:00
|
|
|
bool COpcode::HasArgument() const
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
return ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP));
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int COpcode::GetSize() const
|
|
|
|
|
{
|
2015-02-14 14:38:14 +03:00
|
|
|
if ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP))
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
return OPERATOR_SIZE + ARGUMENT_SIZE;
|
|
|
|
|
}
|
2015-02-14 14:38:14 +03:00
|
|
|
else
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
return OPERATOR_SIZE;
|
|
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
2015-02-15 18:10:01 +03:00
|
|
|
uint16_t COpcode::GetOperator() const
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
return m_wOperator;
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
2015-02-15 18:10:01 +03:00
|
|
|
void COpcode::SetOperator(uint16_t op)
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
m_wOperator = op;
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
2015-02-15 18:28:27 +03:00
|
|
|
uint32_t COpcode::GetArgument() const
|
2015-02-13 16:59:11 +03:00
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
return m_ulArgument;
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const COpcode::COpcodeAttributes COpcode::GetAttributes() const
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
static CF1OpcodeAttributesMap f1OpcodeAttributes;
|
|
|
|
|
static CF2OpcodeAttributesMap f2OpcodeAttributes;
|
|
|
|
|
|
|
|
|
|
COpcodeAttributes result;
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
if (g_nFalloutVersion == 1)
|
|
|
|
|
{
|
|
|
|
|
if (f1OpcodeAttributes.Lookup(m_wOperator, result))
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 14:38:14 +03:00
|
|
|
if (!f2OpcodeAttributes.Lookup(m_wOperator, result))
|
|
|
|
|
{
|
2015-02-14 13:39:47 +03:00
|
|
|
printf("Error: Attempt to obtain attributes of unknown opcode\n");
|
2015-02-15 19:14:18 +03:00
|
|
|
throw std::exception();
|
2015-02-14 13:39:47 +03:00
|
|
|
}
|
2015-02-13 16:59:11 +03:00
|
|
|
|
2015-02-14 13:39:47 +03:00
|
|
|
return result;
|
2015-02-13 16:59:11 +03:00
|
|
|
}
|