Files

158 lines
3.8 KiB
C++
Raw Permalink Normal View History

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>
2015-02-16 00:30:55 +03:00
#include <fstream>
#include <algorithm>
2015-02-15 18:53:04 +03:00
// 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;
2015-02-16 00:30:55 +03:00
extern std::ifstream g_ifstream;
2015-02-13 16:59:11 +03:00
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
}
2015-02-16 00:30:55 +03:00
void COpcode::Serialize()
2015-02-13 16:59:11 +03:00
{
2015-02-16 00:30:55 +03:00
g_ifstream.read((char*)&m_wOperator, sizeof(m_wOperator));
std::reverse((char*)&m_wOperator, (char*)&m_wOperator + sizeof(m_wOperator));
if (!g_ifstream)
2015-02-14 14:38:14 +03:00
{
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)))
{
2015-02-16 00:30:55 +03:00
printf("Error: Invalid opcode at 0x%08x\n", (uint32_t)g_ifstream.tellg() - 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))
{
2015-02-16 00:30:55 +03:00
g_ifstream.read((char*)&m_ulArgument, sizeof(m_ulArgument));
std::reverse((char*)&m_ulArgument, (char*)&m_ulArgument + sizeof(m_ulArgument));
if (!g_ifstream)
2015-02-14 14:38:14 +03:00
{
2015-02-16 00:30:55 +03:00
std::cout << "Error: Unable read opcode argument" << std::endl;
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-16 00:30:55 +03:00
void COpcode::Expect(uint16_t wOperator, bool bArgumentFound, uint32_t ulArgument)
2015-02-13 16:59:11 +03:00
{
2015-02-16 00:30:55 +03:00
Serialize();
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 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
}