From acc1fbd4aa9805dc22dd5e196668809dba2133bf Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Sun, 13 Aug 2023 18:58:04 +0800 Subject: [PATCH] support compile sdcc file --- NEWS.md | 2 +- RedPandaIDE/compiler/sdccfilecompiler.cpp | 126 ++++++++++++++ RedPandaIDE/compiler/sdccfilecompiler.h | 42 +++++ .../templates/epitrochoid/epitrochoid_zh_CN.c | 160 ++++++++++++++++++ 4 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 RedPandaIDE/compiler/sdccfilecompiler.cpp create mode 100644 RedPandaIDE/compiler/sdccfilecompiler.h create mode 100644 platform/linux/templates/epitrochoid/epitrochoid_zh_CN.c diff --git a/NEWS.md b/NEWS.md index 3e126154..7d254a95 100644 --- a/NEWS.md +++ b/NEWS.md @@ -27,7 +27,7 @@ Red Panda C++ Version 2.24 - fix: Wrong compiler settings if xcode is not installed in mac os. - enhancement: Name for new files will not be different from files openned. - fix: Crash if close file while auto syntax checking. - - enhancement: Support sdcc compiler. (Disabled in the distributed buildings) + - enhancement: Support sdcc compiler. - enhancement: Autowrap tool output text. Red Panda C++ Version 2.23 diff --git a/RedPandaIDE/compiler/sdccfilecompiler.cpp b/RedPandaIDE/compiler/sdccfilecompiler.cpp new file mode 100644 index 00000000..2d2817c4 --- /dev/null +++ b/RedPandaIDE/compiler/sdccfilecompiler.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "sdccfilecompiler.h" +#include "utils.h" +#include "../mainwindow.h" +#include "compilermanager.h" +#include "qsynedit/syntaxer/asm.h" +#include "../systemconsts.h" + +#include +#include +#include + + +SDCCFileCompiler::SDCCFileCompiler(const QString &filename, const QByteArray &encoding, + CppCompileType compileType): + Compiler(filename, false,false), + mEncoding(encoding), + mCompileType(compileType) +{ + +} + +bool SDCCFileCompiler::prepareForCompile() +{ + compilerSet()->setCompilationStage(Settings::CompilerSet::CompilationStage::GenerateExecutable); + log(tr("Compiling single file...")); + log("------------------"); + log(tr("- Filename: %1").arg(mFilename)); + log(tr("- Compiler Set Name: %1").arg(compilerSet()->name())); + log(""); + QString ihxFile = changeFileExt(mFilename,SDCC_IHX_SUFFIX); + mOutputFile=changeFileExt(mFilename, compilerSet()->executableSuffix()); + mArguments = QString(" \"%1\"").arg(mFilename); + mArguments+=QString(" -o \"%1\"").arg(ihxFile); + + //remove the old file if it exists + QFile outputFile(mOutputFile); +// if (outputFile.exists()) { +// if (!outputFile.remove()) { +// error(tr("Can't delete the old binary file 2 \"%1\".\n").arg(mOutputFile)); +// return false; +// } +// } + + +// QFile ihxOutputFile(ihxFile); +// if (ihxOutputFile.exists()) { +// if (!outputFile.remove()) { +// error(tr("Can't delete the old binary file 1 \"%1\".\n").arg(ihxFile)); +// return false; +// } +// } + + + if (compilerSet()->executableSuffix() == SDCC_HEX_SUFFIX) { + QString packihx = compilerSet()->findProgramInBinDirs(PACKIHX_PROGRAM); + if (packihx.isEmpty()) { + error(tr("Can't find \"%1\".\n").arg(PACKIHX_PROGRAM)); + return false; + } + mExtraCompilersList.append(packihx); + QString args; + args = QString(" \"%1\"").arg(ihxFile); + mExtraArgumentsList.append(args); + mExtraOutputFilesList.append(mOutputFile); + } else if (compilerSet()->executableSuffix() == SDCC_BIN_SUFFIX) { + QString makebin = compilerSet()->findProgramInBinDirs(MAKEBIN_PROGRAM); + if (makebin.isEmpty()) { + error(tr("Can't find \"%1\".\n").arg(PACKIHX_PROGRAM)); + return false; + } + mExtraCompilersList.push_back(makebin); + QString args; + args = QString(" \"%1\"").arg(ihxFile); + args+=QString(" \"%1\"").arg(mOutputFile); + mExtraArgumentsList.push_back(args); + mExtraOutputFilesList.append(""); + } + + QString strFileType = "C"; + mCompiler = compilerSet()->CCompiler(); + + mArguments += getLibraryArguments(FileType::CSource); + + if (!fileExists(mCompiler)) { + throw CompileError( + tr("The Compiler '%1' doesn't exists!").arg(mCompiler) + +"
" + +tr("Please check the \"program\" page of compiler settings.")); + } + + log(tr("Processing %1 source file:").arg(strFileType)); + log("------------------"); + log(tr("- %1 Compiler: %2").arg(strFileType).arg(mCompiler)); + log(tr("- Command: %1 %2").arg(extractFileName(mCompiler)).arg(mArguments)); + mDirectory = extractFileDir(mFilename); + return true; +} + +bool SDCCFileCompiler::prepareForRebuild() +{ + QString exeName=compilerSet()->getOutputFilename(mFilename); + + QFile file(exeName); + + if (file.exists() && !file.remove()) { + QFileInfo info(exeName); + throw CompileError(tr("Can't delete the old executable file \"%1\".\n").arg(info.absoluteFilePath())); + } + return true; +} diff --git a/RedPandaIDE/compiler/sdccfilecompiler.h b/RedPandaIDE/compiler/sdccfilecompiler.h new file mode 100644 index 00000000..d87b8a51 --- /dev/null +++ b/RedPandaIDE/compiler/sdccfilecompiler.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef SDCCFILECOMPILER_H +#define SDCCFILECOMPILER_H + +#include "compiler.h" + +class SDCCFileCompiler : public Compiler +{ + Q_OBJECT +public: + SDCCFileCompiler(const QString& filename, const QByteArray& encoding, + CppCompileType compileType); + SDCCFileCompiler(const SDCCFileCompiler&)=delete; + SDCCFileCompiler& operator=(const SDCCFileCompiler&)=delete; + +protected: + bool prepareForCompile() override; + +private: + QByteArray mEncoding; + CppCompileType mCompileType; + // Compiler interface +protected: + bool prepareForRebuild() override; +}; + +#endif // SDCCFILECOMPILER_H diff --git a/platform/linux/templates/epitrochoid/epitrochoid_zh_CN.c b/platform/linux/templates/epitrochoid/epitrochoid_zh_CN.c new file mode 100644 index 00000000..d8c26352 --- /dev/null +++ b/platform/linux/templates/epitrochoid/epitrochoid_zh_CN.c @@ -0,0 +1,160 @@ +#include +#include +#include + +#define RAYGUI_IMPLEMENTATION +#include + +/** + * @brief 计算基圆、外旋轮半径和笔尖在外旋轮中位置 + * + * @param baseL 基圆相对半径 + * @param outerL 外旋轮相对半径 + * @param pointL 笔尖在外旋轮中相对位置 + * @param pBaseR 基圆实际半径 + * @param pOuterR 外旋轮实际半径 + * @param pPointR 笔尖在滚动圆中实际位置 + */ +void updateRadius(int baseL, int outerL, int pointL, int *pBaseR, int *pOuterR, int *pPointR) { + int totalL=baseL+outerL; + if (pointL>outerL) + totalL+=pointL; + else + totalL+=outerL; + int totalR = 340; + int remainder = totalR % totalL; + if (remainder!=0) { + if (remainder < totalL / 2) { + totalR -= remainder; + } else { + totalR += ( totalL - remainder); + } + } + *pBaseR = (totalR) / totalL * baseL; + *pOuterR = (totalR) / totalL * outerL; + *pPointR = (totalR) / totalL * pointL; +} + + +int main() { + int baseL=2; //默认基圆相对半径 + int outerL=13; //默认外旋轮相对半径 + int pointL=3; //默认笔尖在滚动圆中相对位置 + int baseR,outerR,pointR; + int cx=350,cy=350; + int speed = 1; + + Color trackColor = BLUE; + updateRadius(baseL, outerL, pointL, &baseR, &outerR, & pointR); + + //初始化绘图窗口 + InitWindow(1000,700,"Epitrochoid"); + SetTraceLogLevel(LOG_WARNING); + SetTargetFPS(60); + + //读取字体文件 + char guichars[]="外旋轮基圆笔尖半径速度颜色清除: 0123456789xABCDEF"; + // 将字符串中的字符逐一转换成Unicode码点,得到码点表 + int codepointsCount; + int *codepoints=LoadCodepoints(guichars,&codepointsCount); + // 读取仅含码点表中各字符的字体 + Font font = LoadFontEx("c:\\windows\\fonts\\simhei.ttf",20,codepoints,codepointsCount); + // 释放码点表 + UnloadCodepoints(codepoints); + + + //设置GUI控件的字体和大小 + GuiSetFont(font); + GuiSetStyle(DEFAULT,TEXT_SIZE,20); + + // 轨迹图层 + Image trackImage=GenImageColor(700,700,WHITE); + // 绘制图层边框 + ImageFillRectangleEx(&trackImage,0,0,700,700,LIGHTGRAY); + ImageFillRectangleEx(&trackImage,5,5,690,690,WHITE); + + //转动圆图层 + Image circlesImage = GenImageColor(700,700,BLANK); + float r=0; + int lastx,lasty; + lasty=cy; + lastx=cx+(baseR+outerR-pointR); + int frameCount = 0; + + //主绘图循环 + while(!WindowShouldClose()) { //窗口未被关闭 + //使用raygui绘制控制面板 + int newOuterL = GuiSliderBar((Rectangle){ 90, 20, 180, 30 },"外旋轮半径",TextFormat("%i", (int)outerL), outerL, 1, 50); + int newBaseL = GuiSliderBar((Rectangle){ 90, 60, 180, 30 },"基圆半径",TextFormat("%i", (int)baseL), baseL, 1, 50); + int newPointL = GuiSliderBar((Rectangle){ 90, 100, 180, 30 },"笔尖半径",TextFormat("%i", (int)pointL), pointL, 1, 50); + speed = GuiSliderBar((Rectangle){ 90, 150, 180, 30 },"速度",TextFormat("%i", (int)speed), speed, 1, 50); + GuiLabel((Rectangle){ 20, 220, 180, 30 },TextFormat("颜色: 0x%02X%02X%02X",(int)(trackColor.r), (int)(trackColor.g),(int)(trackColor.b))); + trackColor= GuiColorPicker((Rectangle){ 50, 250, 196, 192 }, NULL, trackColor); + int doClear = GuiButton((Rectangle){ 120, 500, 80, 30 },"清除"); + if (newOuterL!=outerL || newBaseL!=baseL || newPointL!=pointL) { + //圆参数有变化,清除轨迹图层 + if (newOuterL!=outerL) + pointL=newOuterL; + else + pointL=newPointL; + outerL=newOuterL; + baseL=newBaseL; + updateRadius(baseL, outerL, pointL, &baseR, &outerR, & pointR); + lasty=cy; + lastx=cx+(baseR+outerR-pointR); + r=0; + ImageClearBackground(&trackImage,WHITE); + ImageFillRectangleEx(&trackImage,0,0,700,700,LIGHTGRAY); + ImageFillRectangleEx(&trackImage,5,5,690,690,WHITE); + } else if (doClear) { + //按下了清除按钮,清除轨迹图层 + ImageClearBackground(&trackImage,WHITE); + ImageFillRectangleEx(&trackImage,0,0,700,700,LIGHTGRAY); + ImageFillRectangleEx(&trackImage,5,5,690,690,WHITE); + } + + //更新圆位置 + r+=0.01; + float outerCX=cx+ (baseR+outerR)*cos(r); + float outerCY=cy+ (baseR+outerR)*sin(r); + float theta = r * (baseL+outerL) / outerL; + int x=round(outerCX - pointR * cos(theta)); + int y=round(outerCY - pointR * sin(theta)); + + //更新轨迹 + ImageDrawLineEx(&trackImage,lastx,lasty,x,y,3,trackColor); + + frameCount++; + if (frameCount>=speed) { + //更新转动圆图层中各圆的位置 + ImageClearBackground(&circlesImage,BLANK); + + ImageDrawCircleEx(&circlesImage,cx,cy,baseR,1,LIGHTRED); + ImageDrawCircleEx(&circlesImage,outerCX,outerCY,outerR,1,LIGHTSLATEGRAY); + ImageDrawLineEx(&circlesImage,cx,cy,outerCX,outerCY,1,LIGHTRED); + ImageDrawLineEx(&circlesImage,x,y,outerCX,outerCY,1,LIGHTSLATEGRAY); + ImageDrawPointEx(&circlesImage,x,y,7,RED); + + //将图层绘制到屏幕中(GPU绘图) + Texture trackTexture = LoadTextureFromImage(trackImage); + Texture circlesTexture = LoadTextureFromImage(circlesImage); + BeginDrawing(); + ClearBackground(WHITE); + DrawTexture(trackTexture,300,0,WHITE); + DrawTexture(circlesTexture,300,0,WHITE); + EndDrawing(); + UnloadTexture(circlesTexture); + UnloadTexture(trackTexture); + frameCount=0; + } + + lastx=x; + lasty=y; + } + + //释放图层资源 + UnloadImage(circlesImage); + UnloadImage(trackImage); + //关闭窗口 + CloseWindow(); +} \ No newline at end of file