static bool FnLayerSetPixel(C4PropList * _this, int32_t x, int32_t y, const C4Value& fg_value_c4v, const C4Value& bg_value_c4v) { // Layer script function: Set pixel at position x,y to to_value in _this layer C4MapScriptLayer *layer = _this->GetMapScriptLayer(); if (!layer) return false; uint8_t fg, bg; if (fg_value_c4v.GetType() == C4V_Nil) { fg = layer->GetPix(x,y,0); } else { const C4Value& val = fg_value_c4v; C4String *str = val.getStr(); if (str != NULL) { if (!TexColSingle(str->GetCStr(), fg)) throw C4AulExecError("MapLayer::SetPixel: Trying to set invalid pixel value."); } else { if (!Inside(val.getInt(), 0, 255)) throw C4AulExecError("MapLayer::SetPixel: Trying to set invalid pixel value."); fg = val.getInt(); } } if (bg_value_c4v.GetType() == C4V_Nil) { bg = layer->GetBackPix(x,y,0); } else { const C4Value& val = bg_value_c4v; C4String *str = val.getStr(); if (str != NULL) { if (!TexColSingle(str->GetCStr(), bg)) throw C4AulExecError("MapLayer::SetPixel: Trying to set invalid pixel value."); } else { if (!Inside(val.getInt(), 0, 255)) throw C4AulExecError("MapLayer::SetPixel: Trying to set invalid pixel value."); bg = val.getInt(); } } return layer->SetPix(x,y,fg,bg); }
void C4ParticleValueProvider::SetParameterValue(int type, const C4Value &value, float C4ParticleValueProvider::*floatVal, int C4ParticleValueProvider::*intVal, size_t keyFrameIndex) { // just an atomic data type if (value.GetType() == C4V_Int) { if (type == VAL_TYPE_FLOAT) this->*floatVal = (float)value.getInt(); else if (type == VAL_TYPE_INT) this->*intVal = value.getInt(); else if (type == VAL_TYPE_KEYFRAMES) this->keyFrames[keyFrameIndex] = (float)value.getInt(); } else if (value.GetType() == C4V_Array) { // might be another value provider! C4ParticleValueProvider *child = new C4ParticleValueProvider(); childrenValueProviders.push_back(child); child->Set(*value.getArray()); child->typeOfValueToChange = type; if (type == VAL_TYPE_FLOAT) { child->floatValueToChange = floatVal; } else if (type == VAL_TYPE_INT) { child->intValueToChange = intVal; } else if (type == VAL_TYPE_KEYFRAMES) { child->keyFrameIndex = keyFrameIndex; } } else // invalid { if (type == VAL_TYPE_FLOAT) this->*floatVal = 0.f; else if (type == VAL_TYPE_INT) this->*intVal = 0; else if (type == VAL_TYPE_KEYFRAMES) this->keyFrames[keyFrameIndex] = 0.f; } }
void C4ValueArray::SetSlice(int32_t startIndex, int32_t endIndex, const C4Value &Val) { // maximum bounds if(startIndex >= MaxSize) throw C4AulExecError("array slice: start index exceeds maximum capacity"); // index from back if(startIndex < 0) startIndex += iSize; if(endIndex < 0) endIndex += iSize; // ensure relevant bounds if(startIndex < 0) throw C4AulExecError("array slice: start index out of range"); if(endIndex < 0) throw C4AulExecError("array slice: end index out of range"); if(endIndex < startIndex) endIndex = startIndex; // setting an array? if(Val.GetType() == C4V_Array) { const C4ValueArray &Other = *Val._getArray(); // Remember that &Other could be equal to this, carefull with modifying pData // Calculcate new size int32_t iNewEnd = std::min(startIndex + Other.GetSize(), (int32_t)MaxSize); int32_t iNewSize = iNewEnd; if(endIndex < iSize) iNewSize += iSize - endIndex; iNewSize = std::min(iNewSize, (int32_t)MaxSize); int32_t iOtherSize = Other.GetSize(); if(iNewSize != iSize) { int32_t i,j; C4Value* pnData = pData; if(iNewSize > iCapacity) { pnData = new C4Value [iNewSize]; // Copy first part of old array for(i = 0; i < startIndex && i < iSize; ++i) pnData[i] = pData[i]; } // Copy the second slice of the new array for(i = iNewEnd, j = endIndex; i < iNewSize; ++i, ++j) { assert(j < iSize); pnData[i] = pData[j]; } // Copy the data // Since pnData and pData can be the same, we can not copy with //for(i = startIndex, j = 0; i < iNewEnd; ++i, ++j) // but have to start from the end of the copied sequence. That works, since j <= i for(i = iNewEnd - 1, j = iNewEnd - startIndex - 1; i >= startIndex; --i, --j) { assert(j < iOtherSize); pnData[i] = Other.pData[j]; } // Other values should have been initialized to 0 by new if(pData != pnData) { delete [] pData; pData = pnData; iCapacity = iSize = iNewSize; } else { // "ignore" the now unused part for(i = iNewSize; i < iSize; ++i) pData[i].Set0(); iSize = iNewSize; } } else // slice has the same size as inserted array // Copy the data. changing pData does not break because if &Other == this and iNewSize == iSize, nothing happens at all for(int32_t i = startIndex, j = 0; j < iOtherSize; i++, j++) pData[i] = Other.pData[j]; } else { /* if(Val.GetType() != C4V_Array) */ if(endIndex > MaxSize) endIndex = iSize; // Need resize? if(endIndex > iSize) SetSize(endIndex); // Fill for(int32_t i = startIndex; i < endIndex; i++) pData[i] = Val; } }
C4AulDebug::ProcessLineResult C4AulDebug::ProcessLine(const StdStrBuf &Line) { // Get command StdStrBuf Cmd; Cmd.CopyUntil(Line.getData(), ' '); // Get data const char *szData = Line.getPtr(Cmd.getLength()); if (*szData) szData++; // Identify command const char *szCmd = Cmd.getData(); if (SEqualNoCase(szCmd, "HELP")) return ProcessLineResult(false, "Yeah, like I'm going to explain that /here/"); else if (SEqualNoCase(szCmd, "BYE") || SEqualNoCase(szCmd, "QUIT")) C4NetIOTCP::Close(PeerAddr); else if (SEqualNoCase(szCmd, "SAY")) ::Control.DoInput(CID_Message, new C4ControlMessage(C4CMT_Normal, szData), CDT_Direct); else if (SEqualNoCase(szCmd, "CMD")) ::MessageInput.ProcessCommand(szData); else if (SEqualNoCase(szCmd, "STP") || SEqualNoCase(szCmd, "S")) eState = DS_Step; else if (SEqualNoCase(szCmd, "GO") || SEqualNoCase(szCmd, "G")) eState = DS_Go; else if (SEqualNoCase(szCmd, "STO") || SEqualNoCase(szCmd, "O")) eState = DS_StepOver; else if (SEqualNoCase(szCmd, "STR") || SEqualNoCase(szCmd, "R")) eState = DS_StepOut; else if (SEqualNoCase(szCmd, "EXC") || SEqualNoCase(szCmd, "E")) { C4AulScriptContext* context = pExec->GetContext(pExec->GetContextDepth()-1); int32_t objectNum = C4ControlScript::SCOPE_Global; if (context && context->Obj && context->Obj->GetObject()) objectNum = context->Obj->GetObject()->Number; ::Control.DoInput(CID_Script, new C4ControlScript(szData, objectNum, true), CDT_Decide); } else if (SEqualNoCase(szCmd, "PSE")) if (Game.IsPaused()) { Game.Unpause(); return ProcessLineResult(true, "Game unpaused."); } else { Game.Pause(); return ProcessLineResult(true, "Game paused."); } else if (SEqualNoCase(szCmd, "LST")) { for (C4AulScript* script = ScriptEngine.Child0; script; script = script->Next) { SendLine(RelativePath(script->ScriptName)); } } // toggle breakpoint else if (SEqualNoCase(szCmd, "TBR")) { using namespace std; // FIXME: this doesn't find functions which were included/appended string scriptPath = szData; size_t colonPos = scriptPath.find(':'); if (colonPos == string::npos) return ProcessLineResult(false, "Missing line in breakpoint request"); int line = atoi(&scriptPath[colonPos+1]); scriptPath.erase(colonPos); C4AulScript *script; for (script = ScriptEngine.Child0; script; script = script->Next) { if (SEqualNoCase(RelativePath(script->ScriptName), scriptPath.c_str())) break; } auto sh = script ? script->GetScriptHost() : NULL; if (sh) { C4AulBCC * found = NULL; for (auto script = ::ScriptEngine.Child0; script; script = script->Next) for (C4PropList *props = script->GetPropList(); props; props = props->GetPrototype()) for (auto fname = props->EnumerateOwnFuncs(); fname; fname = props->EnumerateOwnFuncs(fname)) { C4Value val; if (!props->GetPropertyByS(fname, &val)) continue; auto func = val.getFunction(); if (!func) continue; auto sfunc = func->SFunc(); if (!sfunc) continue; if (sfunc->pOrgScript != sh) continue; for (auto chunk = sfunc->GetCode(); chunk->bccType != AB_EOFN; chunk++) { if (chunk->bccType == AB_DEBUG) { int lineOfThisOne = sfunc->GetLineOfCode(chunk); if (lineOfThisOne == line) { found = chunk; goto Found; } } } } Found: if (found) found->Par.i = !found->Par.i; // activate breakpoint else return ProcessLineResult(false, "Can't set breakpoint (wrong line?)"); } else return ProcessLineResult(false, "Can't find script"); } else if (SEqualNoCase(szCmd, "SST")) { std::list<StdStrBuf*>::iterator it = StackTrace.begin(); for (it++; it != StackTrace.end(); it++) { SendLine("AT", (*it)->getData()); } SendLine("EST"); } else if (SEqualNoCase(szCmd, "VAR")) { C4Value *val = NULL; int varIndex; C4AulScriptContext* pCtx = pExec->GetContext(pExec->GetContextDepth() - 1); if (pCtx) { if ((varIndex = pCtx->Func->ParNamed.GetItemNr(szData)) != -1) { val = &pCtx->Pars[varIndex]; } else if ((varIndex = pCtx->Func->VarNamed.GetItemNr(szData)) != -1) { val = &pCtx->Vars[varIndex]; } } const char* typeName = val ? GetC4VName(val->GetType()) : "any"; StdStrBuf output = FormatString("%s %s %s", szData, typeName, val ? val->GetDataString().getData() : "Unknown"); SendLine("VAR", output.getData()); } else return ProcessLineResult(false, "Can't do that"); return ProcessLineResult(true, ""); }