From a8ba3760f46935710a9cd07e878375c7a898665a Mon Sep 17 00:00:00 2001 From: helios Date: Sun, 9 Aug 2026 18:21:04 +0200 Subject: [PATCH] Smooth animation and add no-visual benchmark --- README.md | 6 +++++- src/main.cpp | 29 +++++++++++++++-------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 12f6866..36a3cb1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,11 @@ values and reports comparisons, moves, and elapsed time. **RUN ALL 8** ends with a fair operation-count chart. Controls: **Pause/Resume**, **Redo**, **Next**, **Run All 8**, and -**Algorithm Menu**. Build with `pio run`, upload with `pio run -t upload`. +**Algorithm Menu**. **No Visual** reruns the selected algorithm without any +animation, touch polling, or intentional delay during the timed section and +reports its duration with microsecond-derived precision. The bar animation is +rendered through a PSRAM-backed canvas for tear-free updates. Build with +`pio run`, upload with `pio run -t upload`. The PlatformIO platform is pinned to the `54.03.21-2` maintenance release, which includes esptool 5.0.2 and avoids the Click API error present with the diff --git a/src/main.cpp b/src/main.cpp index ffca835..cf1882c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,7 @@ #include namespace { -constexpr int N=48, CX=34, CY=142, CW=1212, CH=450; +constexpr int N=48, CX=34, CY=142, CW=1212, CH=410; constexpr uint16_t BG=0x0841,PANEL=0x18E3,PANEL2=0x2125,MUTED=0xBDF7,CYAN=0x2E9F,YELLOW=0xFDC0,GREEN=0x4EE9; struct Rect{int x,y,w,h;bool has(int px,int py)const{return px>=x&&px=y&&py0);return true;} +void chart(bool force=false){uint32_t now=millis();if(!force&&now-lastFrame<16)return;lastFrame=now;barCanvas.fillSprite(BG);int gap=3,bw=(CW-(N-1)*gap)/N;for(int i=0;i0);return true;} void swapv(int x,int y){if(x==y)return;int v=a[x];a[x]=a[y];a[y]=v;moves+=3;}void writev(int i,int v){a[i]=v;moves++;} bool bubble(){for(int end=N-1;end>0;end--){bool changed=false;for(int i=0;ia[i+1]){swapv(i,i+1);changed=true;}if(!frame(i,i+1))return false;}if(!changed)break;}return true;} @@ -44,10 +45,10 @@ bool sortNow(){switch(which){case 0:return bubble();case 1:return insertion();ca void reset(){for(int i=0;i0;i--){int j=random(i+1);int v=base[i];base[i]=base[j];base[j]=v;}} -void menu(){M5.Display.fillScreen(BG);M5.Display.fillRect(0,0,1280,102,PANEL);label("SORTING LAB",34,42,middle_left,&fonts::FreeSansBold24pt7b,TFT_WHITE,PANEL);label("Choose one, or run all on the same shuffled data",1244,42,middle_right,&fonts::FreeSans12pt7b,MUTED,PANEL);for(int i=0;i<8;i++){int col=i%2,row=i/2;Rect r{34+col*614,126+row*112,596,94};M5.Display.fillRoundRect(r.x,r.y,r.w,r.h,16,PANEL2);M5.Display.drawRoundRect(r.x,r.y,r.w,r.h,16,0x31A6);label(alg[i].name,r.x+24,r.y+31,middle_left,&fonts::FreeSansBold12pt7b,TFT_WHITE,PANEL2);label(alg[i].lesson,r.x+24,r.y+67,middle_left,&fonts::FreeSans9pt7b,MUTED,PANEL2);label(alg[i].cost,r.x+r.w-18,r.y+31,middle_right,&fonts::FreeSansBold12pt7b,YELLOW,PANEL2);}Rect sh{34,598,300,78},all{352,598,894,78};button(sh,"NEW SHUFFLE",0x620B);button(all,"RUN ALL 8",0x4A2E);while(true){M5.update();auto t=M5.Touch.getDetail();if(t.wasReleased()){if(sh.has(t.x,t.y)){shuffle();menu();return;}if(all.has(t.x,t.y)){which=0;runAll=true;for(auto&r:results)r=Result{};return;}for(int i=0;i<8;i++){Rect r{34+(i%2)*614,126+(i/2)*112,596,94};if(r.has(t.x,t.y)){which=i;runAll=false;return;}}}delay(12);}} +void menu(){M5.Display.fillScreen(BG);M5.Display.fillRect(0,0,1280,102,PANEL);label("SORTING LAB",34,42,middle_left,&fonts::FreeSansBold24pt7b,TFT_WHITE,PANEL);label("Choose one, or run all on the same shuffled data",1244,42,middle_right,&fonts::FreeSans12pt7b,MUTED,PANEL);for(int i=0;i<8;i++){int col=i%2,row=i/2;Rect r{34+col*614,126+row*112,596,94};uint16_t fill=i==which?0x2B8E:PANEL2;M5.Display.fillRoundRect(r.x,r.y,r.w,r.h,16,fill);M5.Display.drawRoundRect(r.x,r.y,r.w,r.h,16,0x31A6);label(alg[i].name,r.x+24,r.y+31,middle_left,&fonts::FreeSansBold12pt7b,TFT_WHITE,fill);label(alg[i].lesson,r.x+24,r.y+67,middle_left,&fonts::FreeSans9pt7b,MUTED,fill);label(alg[i].cost,r.x+r.w-18,r.y+31,middle_right,&fonts::FreeSansBold12pt7b,YELLOW,fill);}Rect sh{34,598,250,78},fast{302,598,370,78},all{690,598,556,78};button(sh,"NEW SHUFFLE",0x620B);button(fast,"NO-VISUAL BENCHMARK",YELLOW);button(all,"RUN ALL 8",0x4A2E);while(true){M5.update();auto t=M5.Touch.getDetail();if(t.wasReleased()){if(sh.has(t.x,t.y)){shuffle();menu();return;}if(fast.has(t.x,t.y)){benchmark=true;runAll=false;return;}if(all.has(t.x,t.y)){which=0;runAll=true;benchmark=false;for(auto&r:results)r=Result{};return;}for(int i=0;i<8;i++){Rect r{34+(i%2)*614,126+(i/2)*112,596,94};if(r.has(t.x,t.y)){which=i;runAll=false;benchmark=false;return;}}}delay(12);}} } -void setup(){Serial.begin(115200);auto cfg=M5.config();M5.begin(cfg);M5.Display.setRotation(1);M5.Display.setColorDepth(16);M5.Display.setBrightness(180);randomSeed(esp_random());shuffle();Serial.println("Tab5 Sorting Lab ready");} -void loop(){menu();do{reset();runScreen();startMs=millis();bool done=sortNow();if(done){uint32_t elapsed=millis()-startMs-pauseTotal;results[which]={cmp,moves,elapsed,true};result();Serial.printf("%s: %lu comparisons, %lu moves, %lu ms\n",alg[which].name,(unsigned long)cmp,(unsigned long)moves,(unsigned long)elapsed);if(runAll){if(waitFor(1700)&&which<7){which++;continue;}if(which==7){summary();runAll=false;}break;}waitFor(10000);break;}bool again=redo;abortRun=false;if(again)continue;break;}while(true);} +void setup(){Serial.begin(115200);auto cfg=M5.config();M5.begin(cfg);M5.Display.setRotation(1);M5.Display.setColorDepth(16);M5.Display.setBrightness(180);barCanvas.setColorDepth(16);barCanvas.setPsram(true);barCanvas.createSprite(CW,CH);randomSeed(esp_random());shuffle();Serial.println("Tab5 Sorting Lab ready");} +void loop(){menu();do{reset();runScreen();startMs=millis();startUs=micros();bool done=sortNow();if(done){uint32_t elapsedUs=benchmark?(micros()-startUs):(millis()-startMs-pauseTotal)*1000UL;results[which]={cmp,moves,elapsedUs,true};result();Serial.printf("%s: %lu comparisons, %lu moves, %.3f ms%s\n",alg[which].name,(unsigned long)cmp,(unsigned long)moves,elapsedUs/1000.0f,benchmark?" (no visual)":"");if(runAll){if(waitFor(1700)&&which<7){which++;continue;}if(which==7){summary();runAll=false;}break;}waitFor(10000);break;}bool again=redo;abortRun=false;if(again)continue;break;}while(true);}