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

📄 edit.c

📁 电路仿真程序 Classic Ladder is coded 100% in C.It can be used for educational purposes or anything you wan
💻 C
📖 第 1 页 / 共 2 页
字号:
        EditArithmExpr[ EditDatas.Rung.Element[PosiX][PosiY].VarNum ][0] = '\0';    }}void CheckForAllocatingArithmExpr(int PosiX,int PosiY){    int TypeElement = EditDatas.Rung.Element[PosiX][PosiY].Type;    int NumExpr = 0;    int Found = FALSE;    if ( (TypeElement==ELE_COMPAR) || (TypeElement==ELE_OUTPUT_OPERATE) )    {        do        {            /* Expr free ? */            if (EditArithmExpr[ NumExpr ][0]=='\0')            {                Found = TRUE;                /* Allocate this expr for the operate/compar block ! */                EditDatas.Rung.Element[PosiX][PosiY].VarNum = NumExpr;            }            NumExpr++;        }        while( (NumExpr<NBR_ARITHM_EXPR) && (!Found) );    }}void InitBufferRungEdited(){    int x,y;    for (y=0;y<RUNG_HEIGHT;y++)    {        for(x=0;x<RUNG_WIDTH;x++)        {            EditDatas.Rung.Element[x][y].Type = ELE_FREE;            EditDatas.Rung.Element[x][y].ConnectedWithTop = 0;            EditDatas.Rung.Element[x][y].VarType = 0;            EditDatas.Rung.Element[x][y].VarNum = 0;            EditDatas.Rung.Element[x][y].DynamicState = 0;        }    }    EditDatas.Rung.Used = TRUE;    EditDatas.Rung.PrevRung = -1;    EditDatas.Rung.NextRung = -1;}int FindFreeRung(){    int NumFree = -1;    int ScanRung = InfosGene->FirstRung;    do    {        if (!RungArray[ScanRung].Used)            NumFree = ScanRung;        ScanRung++;    }    while( (NumFree==-1)&&(ScanRung<NBR_RUNGS) );    return NumFree;}void AddRung(){    InitBufferRungEdited();    EditDatas.DoBeforeFinalCopy = MODE_ADD;    EditDatas.NumRung = FindFreeRung();    /* we have found a free rung ? */    if (EditDatas.NumRung>=0)    {        EditDatas.ModeEdit = TRUE;        EditDatas.ElementUnderEdit = NULL;        autorize_prevnext_buttons(FALSE);        clear_label_comment();        CopyCurrentArithmExpr();    }}void InsertRung(){    /* not really different than adding a rung... */    AddRung();    EditDatas.DoBeforeFinalCopy = MODE_INSERT;}void ModifyCurrentRung(){    CopyRungToRung(&RungArray[InfosGene->CurrentRung],&EditDatas.Rung);    EditDatas.DoBeforeFinalCopy = MODE_MODIFY;    EditDatas.NumRung = InfosGene->CurrentRung;    EditDatas.ModeEdit = TRUE;    EditDatas.ElementUnderEdit = NULL;    autorize_prevnext_buttons(FALSE);    CopyCurrentArithmExpr();}void DeleteCurrentRung(){    int NextDeleted;    int PrevDeleted;    int NewCurrent;    int OldCurrent;    int x,y;    /* do not destroy the last one ! */    if ( !((InfosGene->CurrentRung==InfosGene->FirstRung) && (InfosGene->CurrentRung==InfosGene->LastRung)) )    {        PrevDeleted = RungArray[InfosGene->CurrentRung].PrevRung;        NextDeleted = RungArray[InfosGene->CurrentRung].NextRung;        NewCurrent = NextDeleted;        /* deleting first rung ?*/        if (InfosGene->CurrentRung==InfosGene->FirstRung)        {            InfosGene->FirstRung = NextDeleted;        }        else        {            RungArray[PrevDeleted].NextRung = NextDeleted;        }        /* deleting last rung ? */        if (InfosGene->CurrentRung==InfosGene->LastRung)        {            InfosGene->LastRung = PrevDeleted;            NewCurrent = InfosGene->LastRung;        }        else        {            RungArray[NextDeleted].PrevRung = PrevDeleted;        }        /* the rung is now free ! */        OldCurrent = InfosGene->CurrentRung;        RungArray[InfosGene->CurrentRung].Used = FALSE;        InfosGene->CurrentRung = NewCurrent;        DrawRung(&RungArray[InfosGene->CurrentRung],TRUE);        refresh_label_comment(&RungArray[InfosGene->CurrentRung]);        /* kill the expressions used on the rung deleted */        for (y=0;y<RUNG_HEIGHT;y++)        {            for(x=0;x<RUNG_WIDTH;x++)            {                if ( (RungArray[OldCurrent].Element[x][y].Type == ELE_COMPAR)                   || (RungArray[OldCurrent].Element[x][y].Type == ELE_OUTPUT_OPERATE) )                {                    strcpy(ArithmExpr[ RungArray[OldCurrent].Element[x][y].VarNum ].Expr,"");                }            }        }    }}void CancelRungEdited(){    EditDatas.ModeEdit = FALSE;    EditDatas.ElementUnderEdit = NULL;    EditDatas.NumElementSelectedInToolBar = -1;    LoadElementProperties(NULL);    DrawRung(&RungArray[InfosGene->CurrentRung],TRUE);    refresh_label_comment(&RungArray[InfosGene->CurrentRung]);    autorize_prevnext_buttons(TRUE);}void ApplyRungEdited(){    int PrevNew;    int NextNew;    save_label_comment_edited();    CopyRungToRung(&EditDatas.Rung,&RungArray[EditDatas.NumRung]);    ApplyNewArithmExpr();    /* if we have added or inserted, we will have to */    /* modify the links between rungs */    /* order is important when setting all this, if multi-tasking : */    /* calc.c is using only .NextRung to updates all the rungs. */    /* and also global FirstRung & LastRung to start and end */    switch(EditDatas.DoBeforeFinalCopy)    {        /* Add rung edited after current rung */        case MODE_ADD:            PrevNew = InfosGene->CurrentRung;            NextNew = RungArray[InfosGene->CurrentRung].NextRung;            RungArray[EditDatas.NumRung].PrevRung = PrevNew;            /* new added is not the last now ? */            if (InfosGene->CurrentRung!=InfosGene->LastRung)            {                RungArray[EditDatas.NumRung].NextRung = NextNew;                RungArray[NextNew].PrevRung = EditDatas.NumRung;            }            RungArray[PrevNew].NextRung = EditDatas.NumRung;            /* we can now update LastRung */            if (InfosGene->CurrentRung==InfosGene->LastRung)            {                InfosGene->LastRung = EditDatas.NumRung;            }            /* Here is the new current ! */            InfosGene->CurrentRung = EditDatas.NumRung;            break;        /* Insert rung edited before current rung */        case MODE_INSERT:            PrevNew = RungArray[InfosGene->CurrentRung].PrevRung;            NextNew = InfosGene->CurrentRung;            RungArray[EditDatas.NumRung].NextRung = NextNew;            /* new added is not the first now ? */            if (InfosGene->CurrentRung!=InfosGene->FirstRung)            {                RungArray[EditDatas.NumRung].PrevRung = PrevNew;                RungArray[PrevNew].NextRung = EditDatas.NumRung;            }            else            {                InfosGene->FirstRung = EditDatas.NumRung;            }            RungArray[NextNew].PrevRung = EditDatas.NumRung;            /* Here is the new current ! */            InfosGene->CurrentRung = EditDatas.NumRung;            break;    }    EditDatas.ModeEdit = FALSE;    EditDatas.ElementUnderEdit = NULL;    EditDatas.NumElementSelectedInToolBar = -1;    LoadElementProperties(NULL);    DrawRung(&RungArray[InfosGene->CurrentRung],TRUE);    autorize_prevnext_buttons(TRUE);}/* When we fall on an "unusable" element of a big one,   we return new posix and posiy of the "alive" block */void CheckForBlocksOfBigElement(int * PosiX,int * PosiY){    int ScanX,ScanY;    int ScanForRule;    /* on an "unusable" ? */    if (EditDatas.Rung.Element[*PosiX][*PosiY].Type==ELE_UNUSABLE)    {        /* we now will have to check for all the "alive" block of           bigs elements */        for (ScanY=0;ScanY<RUNG_HEIGHT;ScanY++)        {            for(ScanX=0;ScanX<RUNG_WIDTH;ScanX++)            {                ScanForRule = 0;                do                {                    /* Is is an element with a rule ? */                    if (EditDatas.Rung.Element[ScanX][ScanY].Type == RulesForSpecialElements[ScanForRule][TYPEELERULE])                    {                        /* Have we clicked in it ? */                        if ( (*PosiX>=ScanX-RulesForSpecialElements[ScanForRule][XSIZEELERULE]-1)                            && (*PosiX<=ScanX)                            && (*PosiY>=ScanY)                            && (*PosiY<=ScanY+RulesForSpecialElements[ScanForRule][YSIZEELERULE]-1) )                        {                            /* We've got it ! */                            /* We make as we have clicked on the "alive" block ! */                            *PosiX = ScanX;                            *PosiY = ScanY;                            return;                        }                    }                    ScanForRule++;                }                while(RulesForSpecialElements[ScanForRule][0]!=-1);            }        }    }}int VerifyRulesForElement(short int NumEle,int PosiX,int PosiY){    int RulePass;    int ItIsOk = TRUE;    int ItIsAnOutputEle = FALSE;    if ( (NumEle==ELE_OUTPUT) || (NumEle==ELE_OUTPUT_NOT)            || (NumEle==ELE_OUTPUT_SET) || (NumEle==ELE_OUTPUT_RESET)            || (NumEle==ELE_OUTPUT_JUMP) || (NumEle==ELE_OUTPUT_OPERATE) )        ItIsAnOutputEle = TRUE;    /* verify for outputs if we are under output zone (right column) */    if ( (PosiX==RUNG_WIDTH-1) && !ItIsAnOutputEle )    {            ItIsOk = FALSE;    }    /* verify for inputs if we are under input zone (not right column) */    if ( (PosiX<RUNG_WIDTH-1) && ItIsAnOutputEle )    {            ItIsOk = FALSE;    }    /* verify if for elements bigger than one block it will fit */    RulePass = 0;    do    {        if ( RulesForSpecialElements[RulePass][TYPEELERULE] == NumEle )        {            if ( (PosiX-RulesForSpecialElements[RulePass][XSIZEELERULE]+1 < 0)                || (PosiY+RulesForSpecialElements[RulePass][YSIZEELERULE]-1 >= RUNG_HEIGHT) )                ItIsOk = FALSE;        }        RulePass++;    }    while(RulesForSpecialElements[RulePass][0]!=-1);    /* verify if we are not on another part of a big element ! */    if (EditDatas.Rung.Element[PosiX][PosiY].Type==ELE_UNUSABLE)        ItIsOk = FALSE;    return ItIsOk;}/* used for destroying or adding a big element *//* when destroying : filling all the blocks with ELE_FREE *//* when adding : filling all the blocks with ELE_UNUSABLE *//* the block "alive" is written elsewhere */void CleanForBigElement(short int NumEle,int PosiX,int PosiY,short int FillWithThis){    int RulePass;    int PassX,PassY;    RulePass = 0;    do    {        if (RulesForSpecialElements[RulePass][TYPEELERULE] == NumEle )        {            for (PassX = PosiX - RulesForSpecialElements[RulePass][XSIZEELERULE] +1 ; PassX<=PosiX ; PassX++)            {                for (PassY = PosiY ; PassY<=PosiY + RulesForSpecialElements[RulePass][YSIZEELERULE] -1 ; PassY++)                {                    CheckForFreeingArithmExpr(PassX,PassY);                    EditDatas.Rung.Element[PassX][PassY].Type = FillWithThis;                    EditDatas.Rung.Element[PassX][PassY].ConnectedWithTop = 0;                    EditDatas.Rung.Element[PassX][PassY].DynamicOutput = 0;                }            }        }        RulePass++;    }    while(RulesForSpecialElements[RulePass][0]!=-1);}void CheckBigElementTopLeft(short int NumEle,int * PosiX){    int RulePass;    RulePass = 0;    do    {        if (RulesForSpecialElements[RulePass][TYPEELERULE] == NumEle )        {            *PosiX = *PosiX + RulesForSpecialElements[RulePass][XSIZEELERULE] - 1;        }        RulePass++;    }    while(RulesForSpecialElements[RulePass][0]!=-1);}/* return TRUE if contact or coil element */int IsASimpleElement(int Element){    int Res = FALSE;    if ( (Element==ELE_INPUT) || (Element==ELE_INPUT_NOT)          || (Element==ELE_RISING_INPUT) || (Element==ELE_FALLING_INPUT)          || (Element==ELE_OUTPUT) || (Element==ELE_OUTPUT_NOT)          || (Element==ELE_OUTPUT_SET) || (Element==ELE_OUTPUT_RESET) )        Res = TRUE;    return Res;}/* click with the mouse in x and y pixels of the rung */void EditElementInRung(double x,double y){    int RungX,RungY;    short int NumElement;    /* correspond to which block ? */    RungX = x/BlockWidth;    RungY = y/BlockHeight;    if ( (RungX<RUNG_WIDTH) && (RungY<RUNG_HEIGHT)        && (EditDatas.NumElementSelectedInToolBar!=-1) )    {        /* check for "unusable" blocks */        if (EditDatas.NumElementSelectedInToolBar==EDIT_POINTER)            CheckForBlocksOfBigElement(&RungX,&RungY);        if (EditDatas.NumElementSelectedInToolBar<ELE_UNUSABLE)        {            NumElement = EditDatas.NumElementSelectedInToolBar;            /* For big element, click insert top-left of the element */            CheckBigElementTopLeft(NumElement,&RungX);            /* already the same element ? => if yes kill it! */            if (NumElement==EditDatas.Rung.Element[RungX][RungY].Type)            {                NumElement = ELE_FREE;            }            /* apply the new element */            if (NumElement==ELE_FREE)            {                /* the blocks other than the "alive" are now free... */                CleanForBigElement(EditDatas.Rung.Element[RungX][RungY].Type,RungX,RungY,ELE_FREE);                EditDatas.Rung.Element[RungX][RungY].DynamicOutput = 0;                EditDatas.Rung.Element[RungX][RungY].Type = NumElement;            }            else            {                if (VerifyRulesForElement(NumElement,RungX,RungY))                {                    /* the blocks other than the "alive" are now free... */                    CleanForBigElement(EditDatas.Rung.Element[RungX][RungY].Type,RungX,RungY,ELE_FREE);                    /* for big element with only one block "alive" we must mark the others */                    /* blocks as unusable */                    CleanForBigElement(NumElement,RungX,RungY,ELE_UNUSABLE);                    // if not a simple element (contact/coil) replaced by a simple element, clean VarNum                    if ( !(IsASimpleElement(NumElement) && IsASimpleElement(EditDatas.Rung.Element[RungX][RungY].Type)) )                    {                        EditDatas.Rung.Element[RungX][RungY].VarNum = 0;                    }                    EditDatas.Rung.Element[RungX][RungY].Type = NumElement;                    CheckForAllocatingArithmExpr(RungX,RungY);                }            }        }        if (EditDatas.NumElementSelectedInToolBar==EDIT_CNX_WITH_TOP)        {            if (EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop)                EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop = 0;            else                EditDatas.Rung.Element[RungX][RungY].ConnectedWithTop = 1;        }        if (EditDatas.NumElementSelectedInToolBar==EDIT_LONG_CONNECTION)        {            int ScanX = RungX;            while(EditDatas.Rung.Element[ScanX][RungY].Type==ELE_FREE && ScanX<RUNG_WIDTH-1 )            {                EditDatas.Rung.Element[ScanX++][RungY].Type = ELE_CONNECTION;            }        }        LoadElementProperties(&EditDatas.Rung.Element[RungX][RungY]);        EditDatas.ElementUnderEdit = &EditDatas.Rung.Element[RungX][RungY];    }}

⌨️ 快捷键说明

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