Ejemplo n.º 1
0
void SlicFrame::AddArg(SS_TYPE type, SlicStackValue value)
{
	Assert(m_argList);
	if(!m_argList)
		return;

	SlicSymbolData *sym;
	switch(type) {
		case SS_TYPE_INT:
			m_argList->AddArg(SA_TYPE_INT, value.m_int);
			break;
		case SS_TYPE_VAR:
			sym = g_slicEngine->GetSymbol(value.m_int);
			if(sym->GetType() == SLIC_SYM_REGION) {
				m_argList->AddArg(SA_TYPE_REGION, sym);
			} else if(sym->GetType() == SLIC_SYM_COMPLEX_REGION) {
				m_argList->AddArg(SA_TYPE_COMPLEX_REGION, sym);
			} else {
				m_argList->AddArg(SA_TYPE_INT_VAR, sym);
			}
			break;
		case SS_TYPE_SYM:
			sym = value.m_sym;
			Assert(sym);
			if(sym) {
				if(sym->GetType() == SLIC_SYM_REGION) {
					m_argList->AddArg(SA_TYPE_REGION, sym);
				} else if(sym->GetType() == SLIC_SYM_COMPLEX_REGION) {
					m_argList->AddArg(SA_TYPE_COMPLEX_REGION, sym);
				} else {
					m_argList->AddArg(SA_TYPE_INT_VAR, sym);
				}
			}
			break;

		default:
			Assert(FALSE);
			break;
	}
}
Ejemplo n.º 2
0
//----------------------------------------------------------------------------
//
// Name       : SlicSegment::SlicSegment
//
// Description: Constructor from stored object
//
// Parameters : slicifIndex         : index of stored object
//
// Globals    : g_slicObjectArray   : stored objects
//              g_slicEngine        : game engine
//              g_gevManager        : game event manager
//
// Returns    : -
//
// Remark(s)  : - The stored object will be deleted after copying its data.
//              - Event handlers and Slic user functions will be registered.
//
//----------------------------------------------------------------------------
SlicSegment::SlicSegment(sint32 slicifIndex)
:   GameEventHookCallback       (),
    m_type                      (TYPE_DEFAULT),
    m_codeSize                  (0),
    m_num_trigger_symbols       (0),
    m_num_parameters            (0),
    m_enabled                   (TRUE),
    m_specialVariables          (0),
    m_isAlert                   (FALSE),
    m_isHelp                    (FALSE),
    m_event                     (GEV_MAX),
    m_priority                  (PRIORITY_DEFAULT),
    m_fromFile                  (FALSE),
    m_firstLineNumber           (NOT_IN_USE),
    m_id                        (NULL),
    m_code                      (NULL),
    m_uiComponent               (NULL),
    m_filename                  (NULL),
    m_trigger_symbols_indices   (NULL),
    m_trigger_symbols           (NULL),
    m_parameter_indices         (NULL),
    m_parameter_symbols         (NULL),
    m_poolIndex                 (slicifIndex)
{
	std::fill(m_lastShown, m_lastShown + k_MAX_PLAYERS, 0);

	Assert(slicifIndex < g_slicNumEntries);
	struct PSlicObject *pobj = g_slicObjectArray[slicifIndex];

	m_type = pobj->m_type;
	m_id = pobj->m_id;
	m_code = pobj->m_code;
	m_codeSize = pobj->m_codeSize;
	m_fromFile = pobj->m_from_file;
	m_isAlert = pobj->m_is_alert;
	m_isHelp  = pobj->m_is_help;
	m_uiComponent = pobj->m_ui_component;
	m_filename = pobj->m_filename;

	if (m_type == SLIC_OBJECT_TRIGGER)
	{
		free(pobj->m_trigger_symbols);  // never used
	}

	if (m_type == SLIC_OBJECT_FUNCTION)
	{
		if (pobj->m_num_parameters > 0)
		{
			m_parameter_indices = new sint32[pobj->m_num_parameters];
			memcpy(m_parameter_indices, pobj->m_parameters, pobj->m_num_parameters * sizeof(sint32));
		}
		m_num_parameters = pobj->m_num_parameters;
		free(pobj->m_parameters);
	}

	if (m_type == SLIC_OBJECT_HANDLEEVENT)
	{
		switch (pobj->m_priority)
		{
			case SLIC_PRI_PRE:     m_priority = GEV_PRI_Pre;         break;
			case SLIC_PRI_POST:    m_priority = GEV_PRI_Post;        break;
			case SLIC_PRI_PRIMARY: m_priority = GEV_PRI_Primary;     break;
			default:
				m_priority = GEV_PRI_Pre;
				Assert(FALSE);
				break;
		}

		if (g_gevManager)
		{
			m_event = g_gevManager->GetEventIndex(pobj->m_event_name);
			g_gevManager->AddCallback(m_event, m_priority, this);
		}
	}

	g_slicObjectArray[slicifIndex] = NULL;

	m_enabled = TRUE;

	if (g_slicEngine)
	{
		SlicSymbolData *sym = g_slicEngine->GetSymbol(m_id);

		if (sym)
		{
			if((sym->GetType() == SLIC_SYM_ID) ||
			   (sym->GetType() == SLIC_SYM_UFUNC)
			  )
			{
				sym->SetSegment(this);
			}
		}
	}

	free(pobj);
}
Ejemplo n.º 3
0
//----------------------------------------------------------------------------
//
// Name       : DoInstruction
//
// Description: Executes slic intructions that were previously
//              "compiled" by slicif_add_op.
//
// Parameters : SOP op
//
// Globals    : This function is so big no idea.
//
// Returns    : -
//
// Remark(s)  : The behaviour depends on the given SOP type
//              if you define new operatiors you have of course modify
//              or implement the according behaviour of that function.
//
//              This function is called at slic run time.
//
//----------------------------------------------------------------------------
BOOL SlicFrame::DoInstruction(SOP op)
{
	unsigned char* codePtr = &m_segment->m_code[m_offset];
	unsigned char* origCodePtr = &m_segment->m_code[m_offset];
#if defined(SLIC_DOUBLES)
	double dval;
#endif
	
	sint32 ival, ival2; 

	
	SlicStackValue sval1, sval2, sval3;

	SS_TYPE type1, type2, type3;
	SlicSymbolData *symval;
	BOOL stopped = FALSE;
	sint32 sp;
	sint32 res;
	BOOL calcOffset = TRUE;

	//Added by Martin Gühmann for database access
	SlicDBInterface *conduit;
	char* name;

	switch(op) {
		case SOP_PUSHI:
			sval1.m_int = *(reinterpret_cast<sint32 *>(codePtr));
			codePtr += sizeof(sint32);
			m_stack->Push(SS_TYPE_INT, sval1);
			break;

		case SOP_PUSHD:
#if defined(SLIC_DOUBLES)
			dval = *((double*)codePtr);
            // Probably some handling missing here. Now, we just skip some bytes.
#endif
			codePtr += sizeof(sint32);
			break;

		case SOP_PUSHV:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(int);
			sval1.m_sym = g_slicEngine->GetSymbol(ival);
			if (sval1.m_sym) 
            {
                m_stack->Push(SS_TYPE_SYM, sval1);
            }
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL symbol %d\n", ival));
				stopped = TRUE;
			}
			break;

		case SOP_PUSHM:
		{
			ival = *((sint32*)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL struct symbol %d\n", ival));
				stopped = TRUE;
				break;
			}

			if(symval->GetType() != SLIC_SYM_STRUCT) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, %s is not a struct\n", symval->GetName()));
				stopped = TRUE;
				break;
			}

			SlicStructInstance *theStruct = symval->GetStruct();
			Assert(theStruct);

			ival2 = *((sint32*)codePtr);
			codePtr += sizeof(sint32);
			
			sval1.m_sym = theStruct->GetMemberSymbol(ival2);
			m_stack->Push(SS_TYPE_SYM, sval1);
			break;
		}

		case SOP_PUSHAM:
		{
			
			ival = *((sint32*)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL struct symbol %d\n", ival));
				stopped = TRUE;
				break;
			}

			if(symval->GetType() != SLIC_SYM_ARRAY) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, %s is not an array\n", symval->GetName()));
				stopped = TRUE;
				break;
			}

			
			sp = m_stack->Pop(type3, sval3);
			Assert(sp >= 1);
			
			
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);

			
			if(!symval->ArrayLookup(Eval(type3, sval3), type1, sval1)) {
				DPRINTF(k_DBG_SLIC, ("Couldn't perform array lookup in SOP_PUSHAM\n"));
				stopped = TRUE;
				break;
			}
			
			
			SlicSymbolData * structSym = SlicStack::GetSymbol(type1, sval1);
			if (!structSym) 
            {
				DPRINTF(k_DBG_SLIC, ("Couldn't find struct symbol in SOP_PUSHAM\n"));
				stopped = TRUE;
				break;
			}
			
			if(structSym->GetType() != SLIC_SYM_STRUCT) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, array symbol id not a struct in SOP_PUSHAM\n"));
				stopped = TRUE;
				break;
			}

			SlicStructInstance *theStruct = structSym->GetStruct();
			Assert(theStruct);
			
			
			ival2 = *((sint32*)codePtr);
			codePtr += sizeof(sint32);
			
			sval1.m_sym = theStruct->GetMemberSymbol(ival2);
			m_stack->Push(SS_TYPE_SYM, sval1);
			break;
		}

		case SOP_PUSHA:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(int);
			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL symbol %d\n", ival));
				stopped = TRUE;
				break;
			}

			sval1.m_sym = symval;
			m_stack->Push(SS_TYPE_SYM, sval1);
			break;

		case SOP_AINDX:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 1);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			res = ArrayLookup(type2, sval2, type1, sval1,
							  type3, sval3);
			if(res)
				
				m_stack->Push(type3, sval3);
			else {
				sval3.m_int = 0;
				
				m_stack->Push(SS_TYPE_INT, sval3);
			}
			break;
		case SOP_ADD:  
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) + Eval(type1, sval1);
			
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_SUB:  
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) - Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_MULT: 
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) * Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_EXP: 
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = static_cast<int>
				(pow(static_cast<double>(Eval(type2, sval2)), Eval(type1, sval1)));
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		// Bitwise operators:
		case SOP_BAND: 
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) & Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		case SOP_BOR:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) | Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		case SOP_BXOR:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) ^ Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		case SOP_BNOT:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sval3.m_int = ~Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		case SOP_DIV:  
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			if(Eval(type1, sval1) == 0) {

				//Added by Martin Gühmann
				//It is a problem of slic code and not of the ctp2.exe,
				//the slicer has to solve the problem.
				if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
					c3errors_ErrorDialog("Slic", "In object %s: Division by 0.", m_segment->GetName());
				}
				sval3.m_int = 0;
				m_stack->Push(SS_TYPE_INT, sval3);
				break;
			}
			sval3.m_int = Eval(type2, sval2) / Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_MOD:  
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
            {
                sint32 const    divisor = Eval(type1, sval1);
                if (0 == divisor)
                {
                    // Handle error as for SOP_DIV.
                    if (g_theProfileDB && g_theProfileDB->IsDebugSlic())
                    {
                        c3errors_ErrorDialog("Slic", "In object %s: modulo 0.",
                                             m_segment->GetName()
                                            );
                    }
                    sval3.m_int = 0;
                }
                else
                {
                    sval3.m_int = Eval(type2, sval2) % divisor;
                }
            }
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_EQ:   
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = IsEqual(type2, sval2, type1, sval1);
			
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_GT:   
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) > Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_LT:   
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) < Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_GTE:  

			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) >= Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_LTE:  

			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) <= Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_NEQ:
			
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = !IsEqual(type2, sval2, type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_AND:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) && Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_OR:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);
			sval3.m_int = Eval(type2, sval2) || Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);

			break;
		case SOP_NOT:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sval3.m_int = !Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		case SOP_POP:  
			
			
			Assert(FALSE);
			break;
		case SOP_TRIG: 
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sval3.m_int = Eval(type1, sval1);
			if(!sval3.m_int)
				stopped = TRUE;
			break;
		case SOP_ARGE: 
			sp = m_stack->Pop(type1, sval1);			
			AddArg(type1, sval1);
			break;
		case SOP_ARGID:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, NULL symbol %d\n", ival));
				return FALSE;
			}
			if(symval->GetType() != SLIC_SYM_ID) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, symbol %s is not of type ID\n",
						symval->GetName()));
				return FALSE;
			}
			m_argList->AddArg(symval->GetSegment(), symval);
			break;
		case SOP_ARGS: 
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(symval->GetType() != SLIC_SYM_SVAR) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, string arg doesn't have string type\n"));
				return FALSE;
			}
			m_argList->AddArg(SA_TYPE_STRING, sint32(symval->GetStringId()));
			break;
		case SOP_ARGST:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(symval->GetType() != SLIC_SYM_STRING) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, hard string doesn't have hard string type\n"));
				return FALSE;
			}
			m_argList->AddArg(SA_TYPE_HARD_STRING, symval);
			break;
		case SOP_CALL:
		case SOP_CALLR:
		{
			
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, NULL symbol %d\n", ival));
				return FALSE;
			}
			if(symval->GetType() != SLIC_SYM_FUNC && symval->GetType() != SLIC_SYM_UFUNC) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, symbol %s is not a function\n",
						symval->GetName()));
				return FALSE;
			}
			SlicFunc *funcObj = symval->GetFunction();
			SFN_ERROR err;

			if(!funcObj) {
				
				SlicSegment *segment = g_slicEngine->GetSegment(symval->GetName());
				if(!segment || segment->GetType() != SLIC_OBJECT_FUNCTION) {
					DPRINTF(k_DBG_SLIC, ("Undefined function %s\n", symval->GetName()));
					if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
						c3errors_ErrorDialog("Slic", "%s is not a known function", symval->GetName());
					}
					return FALSE;
				}
				
				
				SlicObject * obj = NULL;
				err = segment->Call(m_argList, obj);
				if (obj)
                {
                    if (op == SOP_CALLR) 
                    {
					    if (g_slicEngine->AtBreak()) 
                        {
                            Assert(!m_resultObject); // need stack when failing?
                            if (m_resultObject)
                            {
                                m_resultObject->Release();
                            }
						    m_resultObject  = obj;
					    } 
                        else 
                        {
						    sval1.m_int = obj->GetResult();
						    m_stack->Push(SS_TYPE_INT, sval1);
						    obj->Release();
					    }
                    }
                    else 
                    {
                        // SOP_CALL: result not used
                        obj->Release();
                    }
				}
			} else {
				err = funcObj->Call(m_argList);
				if(op == SOP_CALLR) {
					switch(funcObj->GetReturnType()) {
						case SFR_INT:
							sval1.m_int = funcObj->GetResult().m_int;
							m_stack->Push(SS_TYPE_INT, sval1);
							break;
						default:
							sval1.m_int = 0;
							m_stack->Push(SS_TYPE_INT, sval1);
							Assert(FALSE);
					}
				}
			}
			if(err != SFN_ERROR_OK) {
				ReportSFError(err, symval);
				stopped = TRUE;
			}

			
			m_argStackPtr--;
			Assert(m_argStackPtr >= -1);
			if(m_argStackPtr >= 0) {
				m_argList = &m_argListArray[m_argStackPtr];
			} else if(m_argStackPtr == -1) {
				m_argList = NULL;
			}

			if(g_slicEngine->AtBreak())
				stopped = TRUE;

			break;
		}
		case SOP_EVENT:
		{
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			if(g_gevManager->IsProcessing()) {
				EVENTLOG(("    "));
			}

			EVENTLOG(("Event:%s(", g_gevManager->GetEventName((GAME_EVENT)ival)));

			GameEventArgList *args = m_argList->CreateGameEventArgs((GAME_EVENT)ival);
			EVENTLOG((") : Serial %d\n", g_gevManager->GetNextSerial()));

			g_gevManager->ArglistAddEvent(GEV_INSERT_Tail,
										  (GAME_EVENT)ival,
										  args);
			
			
			m_argStackPtr--;
			Assert(m_argStackPtr >= -1);
			if(m_argStackPtr >= 0) {
				m_argList = &m_argListArray[m_argStackPtr];
			} else if(m_argStackPtr == -1) {
				m_argList = NULL;
			}

			if(g_slicEngine->AtBreak())
				stopped = TRUE;

			break;
		}
		case SOP_SBLK:
			DPRINTF(k_DBG_SLIC, ("dangling SBLK\n"));
			return FALSE;
		case SOP_END:
			stopped = TRUE;
			codePtr += sizeof(sint32); 
			break;
		case SOP_JMP:
			m_offset    = *(reinterpret_cast<sint32 *>(codePtr));
			calcOffset  = FALSE;
			break;
		case SOP_BNT:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			sp = m_stack->Pop(type2, sval2);
			if(!Eval(type2, sval2)) {
				m_offset = ival;
				calcOffset = FALSE;
			}
			break;
		case SOP_BNEV:
			
			
			
			codePtr += sizeof(sint32);
			
			break;
		case SOP_BUTN:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			ival2 = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);

			symval = g_slicEngine->GetSymbol(ival2);
			if(symval->GetType() != SLIC_SYM_SVAR) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, button string arg doesn't have string type\n"));
				return FALSE;
			}
			g_slicEngine->GetContext()->AddButton(new SlicButton(
				(StringId)symval->GetStringId(), m_segment,
				ival, g_slicEngine->GetContext()));
			break;
		case SOP_OCLS:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);

			g_slicEngine->GetContext()->AddButton(new SlicButton(
					 		 -1, m_segment, ival,
							 g_slicEngine->GetContext()));
			break;
		case SOP_STOP:
			stopped = TRUE;
			break;
		case SOP_NEG:
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			sval3.m_int = 0 - Eval(type1, sval1);
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		case SOP_ASSN:
			ival = *((sint32*)codePtr);
			codePtr += sizeof(sint32);

			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL symbol %d\n", ival));
				stopped = TRUE;
				break;
			}

			sp = m_stack->Pop(type1, sval1);
			
			
			SetValue(symval, type1, sval1);
			break;
		case SOP_ASSNA:
			
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL symbol %d in array assignment", ival));
				stopped = TRUE;
				break;
			}

			if(symval->GetType() != SLIC_SYM_ARRAY) {
				if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
					c3errors_ErrorDialog("Slic", "Symbol '%s' used in array assignment is not an array", symval->GetName());
				}
				stopped = TRUE;
				break;
			}

			
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 1);

			
			sp = m_stack->Pop(type3, sval3);
			Assert(sp >= 0);
			
			SetArrayValue(symval, type2, sval2, type3, sval3);
			break;
		case SOP_ASSNM:
		{
			ival = *((sint32*)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			if(!symval) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL struct symbol %d\n", ival));
				stopped = TRUE;
				break;
			}

			if(symval->GetType() != SLIC_SYM_STRUCT) {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, %s is not a struct\n", symval->GetName()));
				stopped = TRUE;
				break;
			}

			SlicStructInstance *theStruct = symval->GetStruct();
			Assert(theStruct);

			ival2 = *((sint32*)codePtr);
			codePtr += sizeof(sint32);
			
			symval = theStruct->GetMemberSymbol(ival2);
			
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			SetValue(symval, type1, sval1);
			break;
		}
		case SOP_ASSNAM:
		{
			

			
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			SlicSymbolData *arraySym = g_slicEngine->GetSymbol(ival);

			
			ival2 = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			
			if(!arraySym) {
				DPRINTF(k_DBG_SLIC, ("Bad Mojo, symbol %d does not exist", ival));
				stopped = TRUE;
				break;
			}

			if(arraySym->GetType() != SLIC_SYM_ARRAY) {
				DPRINTF(k_DBG_SLIC, ("%s is not an array", arraySym->GetName()));
				stopped = TRUE;
				break;
			}

			
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 1);

			
			sp = m_stack->Pop(type2, sval2);
			Assert(sp >= 0);

			if(!arraySym->ArrayLookup(Eval(type2, sval2), type3, sval3)) {
				DPRINTF(k_DBG_SLIC, ("Array lookup, %s[%d], failed\n", 
									 arraySym->GetName(), Eval(type2, sval2)));
				stopped = TRUE;
				break;
			}

			SlicSymbolData *structSym = SlicStack::GetSymbol(type3, sval3);
			if (!structSym) 
			{
				DPRINTF(k_DBG_SLIC, ("Couldn't find symbol for %s[%d]\n",
									 arraySym->GetName(), Eval(type2, sval2)));
				stopped = TRUE;
				break;
			}

			if(structSym->GetType() != SLIC_SYM_STRUCT) {
				DPRINTF(k_DBG_SLIC, ("%s[%d] is not a struct\n",
									 arraySym->GetName(), Eval(type2, sval2)));
				stopped = TRUE;
				break;
			}

			SlicStructInstance *theStruct = structSym->GetStruct();
			Assert(theStruct);

			if(!theStruct) {
				stopped = TRUE;
				break;
			}
			SlicSymbolData *assnSym = theStruct->GetMemberSymbol(ival2);
			assnSym->SetValueFromStackValue(type1, sval1);
			break;
		}			
		case SOP_SARGS:
			
			m_argStackPtr++;
			Assert(m_argStackPtr < k_ARGLIST_STACK_SIZE);
			if(m_argStackPtr < k_ARGLIST_STACK_SIZE) {
				m_argList = &m_argListArray[m_argStackPtr];
				m_argList->Clear();
			}
			break;
		case SOP_RET:
			
			sp = m_stack->Pop(type1, sval1);
			Assert(sp >= 0);
			g_slicEngine->GetContext()->SetResult(Eval(type1, sval1));
			stopped = TRUE;
			break;
		case SOP_LINE:
		case SOP_LBRK:
		{
			
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			m_currentLine = ival;

			ival2 = *((sint32 *)codePtr);
			if(m_segment->GetFilename()) {
				if(ival2 < 0) {
					
					
					*((sint32 *)codePtr) = FindFileOffset(m_segment->GetFilename(), ival);
					ival2 = *((sint32 *)codePtr);
				}
			}

			codePtr += sizeof(sint32);

			SlicConditional *cond = *((SlicConditional **)codePtr);
			codePtr += sizeof(SlicConditional *);

			if(op == SOP_LBRK || g_slicEngine->BreakRequested()) {
				if(!cond || (cond->Eval() != 0)) {
					
					
					g_slicEngine->Break(m_segment, codePtr - m_segment->m_code, 
										g_slicEngine->GetContext(), m_stack,
										m_messageData);
					stopped = TRUE;
				}
			}

			break;
		}
		case SOP_ASIZE:
			ival = *((sint32 *)codePtr);
			codePtr += sizeof(sint32);
			symval = g_slicEngine->GetSymbol(ival);
			Assert(symval);
			if(symval) {
				sval1.m_int = symval->GetArray()->GetSize();
			}
			else{
				sval1.m_int = 0;
			}
			m_stack->Push(SS_TYPE_INT, sval1);
			break;

		//Added by Martin Gühmann for database support
		case SOP_DBNAME:
		{
			conduit     = GetDatabase(codePtr);
			ival        = *((sint32 *)codePtr);
			codePtr    += sizeof(sint32);
			symval      = g_slicEngine->GetSymbol(ival);

			if (conduit && symval) 
            {
			    sval1.m_sym = symval;
			    sval3.m_int = Eval(SS_TYPE_SYM, sval1);		
			
			    if ((sval3.m_int >= 0) && sval3.m_int < conduit->GetNumRecords())
                {	
                    // No action: value is OK
			    }
			    else
                {
				    sval3.m_int = -1;
                }
                
                m_stack->Push(SS_TYPE_INT, sval3);
			}
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL symbol %d\n", ival));
				stopped = TRUE;
			}
			break;
		}
		case SOP_DBNAMEREF:
		{
			conduit     = GetDatabase(codePtr);
			ival        = *((sint32 *)codePtr);
			codePtr    += sizeof(sint32);
			symval      = g_slicEngine->GetSymbol(ival);

			if (conduit && symval) 
            {
                //Get the member:
                name = reinterpret_cast<char *>(codePtr);
                Assert(name);
                for ( ; *codePtr++; )
                {
	                // No action: just skip
                }

                sval1.m_sym = symval;
                sval3.m_int = Eval(SS_TYPE_SYM, sval1);		

                if(sval3.m_int > -1 && sval3.m_int < conduit->GetNumRecords()){		
	                sval3.m_int = conduit->GetValue(sval3.m_int, name);
	                m_stack->Push(SS_TYPE_INT, sval3);
                }
                else{
	                if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
		                c3errors_ErrorDialog("Slic", "In object %s no entry found with index %i in %s.", m_segment->GetName(), sval3.m_int, conduit->GetName());
	                }
	                sval3.m_int = 0;
	                m_stack->Push(SS_TYPE_INT, sval3);
                }
            }
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL symbol %d\n", ival));
				stopped = TRUE;
            }
			break;
		}
		case SOP_DBNAMEARRAY:
		{
			conduit     = GetDatabase(codePtr);
			ival        = *((int*)codePtr);
			codePtr    += sizeof(int);
			symval      = g_slicEngine->GetSymbol(ival);

			if (conduit && symval) 
            {
			    //Get the member:
			    name    = reinterpret_cast<char *>(codePtr);
			    Assert(name);
			    for ( ; *codePtr++ ; )
                {
				    // No action: just skip
			    }

			    sval1.m_sym = symval;
			    sval3.m_int = Eval(SS_TYPE_SYM, sval1);		

			    sp = m_stack->Pop(type2, sval2);
			    Assert(sp >= 0);

			    sval2.m_int = Eval(type2, sval2);

			    if(sval3.m_int > -1 && sval3.m_int < conduit->GetNumRecords()){		
				    sval3.m_int = conduit->GetValue(sval3.m_int, name, sval2.m_int);
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
			    else{
				    if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
					    c3errors_ErrorDialog("Slic", "In object %s no entry found with index %i in %s.", m_segment->GetName(), sval3.m_int, conduit->GetName());
				    }
				    sval3.m_int = 0;
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
            }
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, NULL symbol %d\n", ival));
				stopped = TRUE;
			}

			break;
		}
		case SOP_DBNAMECONSTARRAY:
		{
			conduit     = GetDatabase(codePtr);

            if (conduit)
            {
			    sval3.m_int = *((sint32 *)codePtr);
			    codePtr    += sizeof(sint32);
			    //Get the member:
			    name = reinterpret_cast<char *>(codePtr);
			    Assert(name);
			    for ( ; *codePtr++; )
                {
				    // No action: just skip
			    }

			    sp = m_stack->Pop(type2, sval2);
			    Assert(sp >= 0);

			    sval2.m_int = Eval(type2, sval2);


			    if(sval3.m_int > -1 && sval3.m_int < conduit->GetNumRecords()){		
				    sval3.m_int = conduit->GetValue(sval3.m_int, name, sval2.m_int);
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
			    else{
				    if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
					    c3errors_ErrorDialog("Slic", "In object %s no entry found with index %i in %s.", m_segment->GetName(), sval3.m_int, conduit->GetName());
				    }
				    sval3.m_int = 0;
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
            }
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, incorrect database symbol\n"));
				stopped = TRUE;
            }

			break;
		}
		case SOP_DB:
		{
			conduit = GetDatabase(codePtr);

			if (conduit)
            {
			    sp = m_stack->Pop(type1, sval1);
			    Assert(sp >= 0);

			    sval3.m_int = Eval(type1, sval1);

			    if(sval3.m_int > -1 && sval3.m_int < conduit->GetNumRecords()){		
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
			    else{
				    sval3.m_int = -1;
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
            }
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, incorrect database symbol\n"));
				stopped = TRUE;
            }

			break;
		}
		case SOP_DBREF:
		{
			conduit = GetDatabase(codePtr);

			if (conduit)
            {
			    //Get the member:
			    name = reinterpret_cast<char *>(codePtr);
			    Assert(name);
			    for ( ; *codePtr++ ; )
                {
				    // No action: just skip
			    }

			    sp = m_stack->Pop(type1, sval1);
			    Assert(sp >= 0);

			    sval2.m_int = Eval(type1, sval1);

			    if(sval2.m_int > -1 && sval2.m_int < conduit->GetNumRecords()){		
				    sval3.m_int = conduit->GetValue(sval2.m_int, name);
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
			    else{
				    if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
					    c3errors_ErrorDialog("Slic", "In object %s no entry found with index %i in %s.", m_segment->GetName(), sval2.m_int, conduit->GetName());
				    }
				    sval2.m_int = 0;
				    m_stack->Push(SS_TYPE_INT, sval2);
			    }
            }
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, incorrect database symbol\n"));
				stopped = TRUE;
            }

			break;
		}
		case SOP_DBARRAY:
		{
			conduit = GetDatabase(codePtr);

			if (conduit)
            {
			    //Get the member:
			    name = reinterpret_cast<char *>(codePtr);
			    Assert(name);
			    for ( ; *codePtr++; )
                {
				    // Just skip
			    }

			    sp = m_stack->Pop(type1, sval1);
			    Assert(sp >= 0);

			    sval1.m_int = Eval(type1, sval1);

			    sp = m_stack->Pop(type2, sval2);
			    Assert(sp >= 0);

			    sval2.m_int = Eval(type2, sval2);

			    if(sval2.m_int > -1 && sval2.m_int < conduit->GetNumRecords()){		
				    sval3.m_int = conduit->GetValue(sval2.m_int, name, sval1.m_int);
				    m_stack->Push(SS_TYPE_INT, sval3);
			    }
			    else{
				    if(g_theProfileDB && g_theProfileDB->IsDebugSlic()) {
					    c3errors_ErrorDialog("Slic", "In object %s no entry found with index %i in %s.", m_segment->GetName(), sval2.m_int, conduit->GetName());
				    }
				    sval2.m_int = 0;
				    m_stack->Push(SS_TYPE_INT, sval2);
			    }
            }
            else
            {
				DPRINTF(k_DBG_SLIC, ("Bad mojo, incorrect database symbol\n"));
				stopped = TRUE;
            }
            
			break;
		}
		case SOP_DBSIZE:
		{
			//Added by Martin Gühmann to figure out via 
			//slic how many records the database contains
			//Get the database:
			conduit = GetDatabase(codePtr);
			Assert(conduit);
			if (conduit)
            {
				sval3.m_int = conduit->GetNumRecords();
			}
			else
            {
				sval3.m_int = 0;
			}
			m_stack->Push(SS_TYPE_INT, sval3);
			break;
		}

		default:
			DPRINTF(k_DBG_SLIC, ("???\n"));
			break;
	}
	if(calcOffset)
		m_offset += codePtr - origCodePtr;
	return !stopped;
}