From f2afbca6ec2fa0a75e00206eb4ef53cd8361447b Mon Sep 17 00:00:00 2001 From: Jacob Litewski Date: Sat, 13 Apr 2024 23:03:35 -0400 Subject: [PATCH] Refactored Plot Annotations and some cleanup --- client/src/cmddata.c | 32 ++--- client/src/cmdlfawid.c | 2 +- client/src/cmdlfem4x05.c | 2 +- client/src/cmdlfhid.c | 2 +- client/src/cmdlfindala.c | 2 +- client/src/cmdlfio.c | 2 +- client/src/cmdlfparadox.c | 2 +- client/src/cmdlfpyramid.c | 2 +- client/src/cmdlft55xx.c | 2 +- client/src/graph.c | 95 ++++++++----- client/src/graph.h | 13 +- client/src/proxguiqt.cpp | 285 ++++++++++++++++++++++++++++++-------- client/src/proxguiqt.h | 2 + 13 files changed, 328 insertions(+), 115 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 902913989..bc12443d3 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -447,7 +447,7 @@ int ASKDemod_ext(int clk, int invert, int maxErr, size_t maxlen, bool amplify, b return PM3_EMALLOC; } - size_t bitlen = getFromGraphBuf(bits); + size_t bitlen = getFromGraphBuffer(bits); PrintAndLogEx(DEBUG, "DEBUG: (ASKDemod_ext) #samples from graphbuff: %zu", bitlen); @@ -760,7 +760,7 @@ int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose) { return PM3_EMALLOC; } - size_t size = getFromGraphBufEx(bs, MAX_DEMOD_BUF_LEN); + size_t size = getFromGraphBufferEx(bs, MAX_DEMOD_BUF_LEN); if (size == 0) { PrintAndLogEx(DEBUG, "DEBUG: no data in graphbuf"); free(bs); @@ -1298,7 +1298,7 @@ int FSKrawDemod(uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow, bo return PM3_EMALLOC; } - size_t bitlen = getFromGraphBuf(bits); + size_t bitlen = getFromGraphBuffer(bits); if (bitlen == 0) { PrintAndLogEx(DEBUG, "DEBUG: no data in graphbuf"); free(bits); @@ -1400,7 +1400,7 @@ int PSKDemod(int clk, int invert, int maxErr, bool verbose) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t bitlen = getFromGraphBuf(bits); + size_t bitlen = getFromGraphBuffer(bits); if (bitlen == 0) { free(bits); return PM3_ESOFT; @@ -1451,7 +1451,7 @@ int NRZrawDemod(int clk, int invert, int maxErr, bool verbose) { return PM3_EMALLOC; } - size_t bitlen = getFromGraphBuf(bits); + size_t bitlen = getFromGraphBuffer(bits); if (bitlen == 0) { free(bits); @@ -1821,10 +1821,10 @@ int CmdHpf(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); removeSignalOffset(bits, size); // push it back to graph - setGraphBuf(bits, size); + setGraphBuffer(bits, size); // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(bits, size); @@ -1929,7 +1929,7 @@ int getSamplesFromBufEx(uint8_t *data, size_t sample_num, uint8_t bits_per_sampl PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(bits, size); free(bits); @@ -2039,10 +2039,10 @@ static int CmdLoad(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); removeSignalOffset(bits, size); - setGraphBuf(bits, size); + setGraphBuffer(bits, size); computeSignalProperties(bits, size); free(bits); } @@ -2186,7 +2186,7 @@ int CmdNorm(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(bits, size); @@ -2337,7 +2337,7 @@ static int CmdDirectionalThreshold(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); // set signal properties low/high/mean/amplitude and is_noice detection computeSignalProperties(bits, size); @@ -2385,7 +2385,7 @@ static int CmdZerocrossings(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(bits, size); RepaintGraphWindow(); @@ -2600,7 +2600,7 @@ static int CmdDataIIR(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(bits, size); RepaintGraphWindow(); @@ -3336,7 +3336,7 @@ static int CmdCenterThreshold(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); // set signal properties low/high/mean/amplitude and is_noice detection computeSignalProperties(bits, size); RepaintGraphWindow(); @@ -3386,7 +3386,7 @@ static int CmdEnvelope(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); // set signal properties low/high/mean/amplitude and is_noice detection computeSignalProperties(bits, size); RepaintGraphWindow(); diff --git a/client/src/cmdlfawid.c b/client/src/cmdlfawid.c index 7d944df25..e3a0d78bc 100644 --- a/client/src/cmdlfawid.c +++ b/client/src/cmdlfawid.c @@ -149,7 +149,7 @@ int demodAWID(bool verbose) { return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - AWID not enough samples"); free(bits); diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index 65db29ed5..bc6d731e6 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -175,7 +175,7 @@ static bool em4x05_download_samples(void) { return false; } - setGraphBuf(got, sizeof(got)); + setGraphBuffer(got, sizeof(got)); // set signal properties low/high/mean/amplitude and is_noise detection computeSignalProperties(got, sizeof(got)); RepaintGraphWindow(); diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index b5ae61d6a..e1cc1f00f 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -122,7 +122,7 @@ int demodHID(bool verbose) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - " _RED_("HID not enough samples")); free(bits); diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index 9abcf90c9..0b5c7bd0a 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -408,7 +408,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t datasize = getFromGraphBuf(data); + size_t datasize = getFromGraphBuffer(data); uint8_t rawbits[4096] = {0}; int rawbit = 0; diff --git a/client/src/cmdlfio.c b/client/src/cmdlfio.c index 7c106dee7..ad4517732 100644 --- a/client/src/cmdlfio.c +++ b/client/src/cmdlfio.c @@ -71,7 +71,7 @@ int demodIOProx(bool verbose) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size < 65) { PrintAndLogEx(DEBUG, "DEBUG: Error - IO prox not enough samples in GraphBuffer"); free(bits); diff --git a/client/src/cmdlfparadox.c b/client/src/cmdlfparadox.c index 937f11510..70906b58d 100644 --- a/client/src/cmdlfparadox.c +++ b/client/src/cmdlfparadox.c @@ -108,7 +108,7 @@ int demodParadox(bool verbose, bool oldChksum) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - Paradox not enough samples"); free(bits); diff --git a/client/src/cmdlfpyramid.c b/client/src/cmdlfpyramid.c index 3d711c23d..470d0e697 100644 --- a/client/src/cmdlfpyramid.c +++ b/client/src/cmdlfpyramid.c @@ -48,7 +48,7 @@ int demodPyramid(bool verbose) { PrintAndLogEx(FAILED, "failed to allocate memory"); return PM3_EMALLOC; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(DEBUG, "DEBUG: Error - Pyramid not enough samples"); free(bits); diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index d92d9dbc7..16087be4a 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -2900,7 +2900,7 @@ static int CmdResetRead(const char *Cmd) { free(got); return PM3_ETIMEOUT; } - setGraphBuf(got, gotsize); + setGraphBuffer(got, gotsize); free(got); } diff --git a/client/src/graph.c b/client/src/graph.c index 7d77aabf2..352bbbb5f 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -25,9 +25,11 @@ #include "cmddata.h" //for g_debugmode -int g_GraphBuffer[MAX_GRAPH_TRACE_LEN]; -int g_OperationBuffer[MAX_GRAPH_TRACE_LEN]; -size_t g_GraphTraceLen; +int32_t g_GraphBuffer[MAX_GRAPH_TRACE_LEN]; +int32_t g_OperationBuffer[MAX_GRAPH_TRACE_LEN]; +int32_t g_OverlayBuffer[MAX_GRAPH_TRACE_LEN]; +bool g_useOverlays = false; +size_t g_GraphTraceLen; /* write a manchester bit to the graph */ @@ -65,44 +67,49 @@ void AppendGraph(bool redraw, uint16_t clock, int bit) { } } -// clear out our graph window +// clear out our graph window and all the buffers associated with it size_t ClearGraph(bool redraw) { size_t gtl = g_GraphTraceLen; + memset(g_GraphBuffer, 0x00, g_GraphTraceLen); memset(g_OperationBuffer, 0x00, g_GraphTraceLen); + memset(g_OverlayBuffer, 0x00, g_GraphTraceLen); + g_GraphTraceLen = 0; g_GraphStart = 0; g_GraphStop = 0; - g_DemodBufferLen = 0; - if (redraw) + g_useOverlays = false; + + if (redraw) { RepaintGraphWindow(); + } return gtl; } // option '1' to save g_GraphBuffer any other to restore void save_restoreGB(uint8_t saveOpt) { - static int SavedGB[MAX_GRAPH_TRACE_LEN]; - static size_t SavedGBlen = 0; - static bool GB_Saved = false; - static int Savedg_GridOffsetAdj = 0; + static int savedBuffer[MAX_GRAPH_TRACE_LEN]; + static size_t savedBufferLen = 0; + static bool bufferSaved = false; + static int savedOffset = 0; if (saveOpt == GRAPH_SAVE) { //save - memcpy(SavedGB, g_GraphBuffer, sizeof(g_GraphBuffer)); - SavedGBlen = g_GraphTraceLen; - GB_Saved = true; - Savedg_GridOffsetAdj = g_GridOffset; - } else if (GB_Saved) { //restore - memcpy(g_GraphBuffer, SavedGB, sizeof(g_GraphBuffer)); - memcpy(g_OperationBuffer, SavedGB, sizeof(g_OperationBuffer)); - g_GraphTraceLen = SavedGBlen; - g_GridOffset = Savedg_GridOffsetAdj; + memcpy(savedBuffer, g_GraphBuffer, sizeof(g_GraphBuffer)); + savedBufferLen = g_GraphTraceLen; + bufferSaved = true; + savedOffset = g_GridOffset; + } else if (bufferSaved) { //restore + memcpy(g_GraphBuffer, savedBuffer, sizeof(g_GraphBuffer)); + memcpy(g_OperationBuffer, savedBuffer, sizeof(g_OperationBuffer)); + g_GraphTraceLen = savedBufferLen; + g_GridOffset = savedOffset; RepaintGraphWindow(); } } -void setGraphBuf(const uint8_t *src, size_t size) { +void setGraphBuffer(const uint8_t *src, size_t size) { if (src == NULL) return; ClearGraph(false); @@ -121,12 +128,12 @@ void setGraphBuf(const uint8_t *src, size_t size) { } // This function assumes that the length of dest array >= g_GraphTraceLen. -// If the length of dest array is less than g_GraphTraceLen, use getFromGraphBufEx(dest, maxLen) instead. -size_t getFromGraphBuf(uint8_t *dest) { - return getFromGraphBufEx(dest, g_GraphTraceLen); +// If the length of dest array is less than g_GraphTraceLen, use getFromGraphBufferEx(dest, maxLen) instead. +size_t getFromGraphBuffer(uint8_t *dest) { + return getFromGraphBufferEx(dest, g_GraphTraceLen); } -size_t getFromGraphBufEx(uint8_t *dest, size_t maxLen) { +size_t getFromGraphBufferEx(uint8_t *dest, size_t maxLen) { if (dest == NULL) return 0; if (g_GraphTraceLen == 0) return 0; @@ -141,12 +148,38 @@ size_t getFromGraphBufEx(uint8_t *dest, size_t maxLen) { return i; } -// A simple test to see if there is any data inside Graphbuffer. +//TODO: In progress function to get chunks of data from the GB w/o modifying the GB +//Currently seems like it doesn't work correctly? +size_t getGraphBufferChunk(uint8_t *dest, size_t start, size_t end) { + if (dest == NULL) return 0; + if (g_GraphTraceLen == 0) return 0; + if (start >= end) return 0; + + size_t i, value; + end = (end < g_GraphTraceLen) ? end : g_GraphTraceLen; + for (i = 0; i < (end - start); i++) { + value = g_GraphBuffer[start + i]; + + //Trim the data to fit into an uint8_t + if (value > 127) { + value = 127; + } else if (value < -127) { + value = -127; + } + + dest[i] = ((uint8_t)(value + 128)); + } + + return i; +} + +// A simple test to see if there is any data inside the Graph Buffer. bool HasGraphData(void) { if (g_GraphTraceLen == 0) { PrintAndLogEx(NORMAL, "No data available, try reading something first"); return false; } + return true; } @@ -180,7 +213,7 @@ void convertGraphFromBitstreamEx(int hi, int low) { return; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); @@ -210,7 +243,7 @@ int GetAskClock(const char *str, bool verbose) { return -1; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); @@ -245,7 +278,7 @@ int GetPskCarrier(bool verbose) { return -1; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); @@ -281,7 +314,7 @@ int GetPskClock(const char *str, bool verbose) { return -1; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); @@ -319,7 +352,7 @@ int GetNrzClock(const char *str, bool verbose) { return -1; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); @@ -375,7 +408,7 @@ bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge) { return false; } - size_t size = getFromGraphBuf(bits); + size_t size = getFromGraphBuffer(bits); if (size == 0) { PrintAndLogEx(WARNING, "Failed to copy from graphbuffer"); free(bits); diff --git a/client/src/graph.h b/client/src/graph.h index b5cbf99e0..58a05ed9b 100644 --- a/client/src/graph.h +++ b/client/src/graph.h @@ -28,10 +28,11 @@ extern "C" { void AppendGraph(bool redraw, uint16_t clock, int bit); size_t ClearGraph(bool redraw); bool HasGraphData(void); -void setGraphBuf(const uint8_t *src, size_t size); +void setGraphBuffer(const uint8_t *src, size_t size); void save_restoreGB(uint8_t saveOpt); -size_t getFromGraphBuf(uint8_t *dest); -size_t getFromGraphBufEx(uint8_t *dest, size_t maxLen); +size_t getFromGraphBuffer(uint8_t *dest); +size_t getFromGraphBufferEx(uint8_t *dest, size_t maxLen); +size_t getGraphBufferChunk(uint8_t *dest, size_t start, size_t end); void convertGraphFromBitstream(void); void convertGraphFromBitstreamEx(int hi, int low); bool isGraphBitstream(void); @@ -47,8 +48,10 @@ bool fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, int *firstClockEdge); #define GRAPH_SAVE 1 #define GRAPH_RESTORE 0 -extern int g_GraphBuffer[MAX_GRAPH_TRACE_LEN]; -extern int g_OperationBuffer[MAX_GRAPH_TRACE_LEN]; +extern int32_t g_GraphBuffer[MAX_GRAPH_TRACE_LEN]; +extern int32_t g_OperationBuffer[MAX_GRAPH_TRACE_LEN]; +extern int32_t g_OverlayBuffer[MAX_GRAPH_TRACE_LEN]; +extern bool g_useOverlays; extern size_t g_GraphTraceLen; #ifdef __cplusplus diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index fa141bbe1..514b2920c 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -45,8 +45,6 @@ extern "C" int preferences_save(void); -static int s_OverlayBuff[MAX_GRAPH_TRACE_LEN]; -static bool gs_useOverlays = false; static int gs_absVMax = 0; static uint32_t startMax; // Maximum offset in the graph (right side of graph) static uint32_t startMaxOld; @@ -340,7 +338,7 @@ void SliderWidget::moveEvent(QMoveEvent *event) { void ProxWidget::applyOperation() { //printf("ApplyOperation()"); save_restoreGB(GRAPH_SAVE); - memcpy(g_GraphBuffer, s_OverlayBuff, sizeof(int) * g_GraphTraceLen); + memcpy(g_GraphBuffer, g_OverlayBuffer, sizeof(int) * g_GraphTraceLen); RepaintGraphWindow(); } void ProxWidget::stickOperation() { @@ -348,30 +346,30 @@ void ProxWidget::stickOperation() { //printf("stickOperation()"); } void ProxWidget::vchange_autocorr(int v) { - int ans = AutoCorrelate(g_GraphBuffer, s_OverlayBuff, g_GraphTraceLen, v, true, false); + int ans = AutoCorrelate(g_GraphBuffer, g_OverlayBuffer, g_GraphTraceLen, v, true, false); if (g_debugMode) printf("vchange_autocorr(w:%d): %d\n", v, ans); - gs_useOverlays = true; + g_useOverlays = true; RepaintGraphWindow(); } void ProxWidget::vchange_askedge(int v) { //extern int AskEdgeDetect(const int *in, int *out, int len, int threshold); - int ans = AskEdgeDetect(g_GraphBuffer, s_OverlayBuff, g_GraphTraceLen, v); + int ans = AskEdgeDetect(g_GraphBuffer, g_OverlayBuffer, g_GraphTraceLen, v); if (g_debugMode) printf("vchange_askedge(w:%d)%d\n", v, ans); - gs_useOverlays = true; + g_useOverlays = true; RepaintGraphWindow(); } void ProxWidget::vchange_dthr_up(int v) { int down = opsController->horizontalSlider_dirthr_down->value(); - directionalThreshold(g_GraphBuffer, s_OverlayBuff, g_GraphTraceLen, v, down); + directionalThreshold(g_GraphBuffer, g_OverlayBuffer, g_GraphTraceLen, v, down); //printf("vchange_dthr_up(%d)", v); - gs_useOverlays = true; + g_useOverlays = true; RepaintGraphWindow(); } void ProxWidget::vchange_dthr_down(int v) { //printf("vchange_dthr_down(%d)", v); int up = opsController->horizontalSlider_dirthr_up->value(); - directionalThreshold(g_GraphBuffer, s_OverlayBuff, g_GraphTraceLen, v, up); - gs_useOverlays = true; + directionalThreshold(g_GraphBuffer, g_OverlayBuffer, g_GraphTraceLen, v, up); + g_useOverlays = true; RepaintGraphWindow(); } @@ -485,7 +483,7 @@ ProxWidget::~ProxWidget(void) { void ProxWidget::closeEvent(QCloseEvent *event) { event->ignore(); this->hide(); - gs_useOverlays = false; + g_useOverlays = false; } void ProxWidget::hideEvent(QHideEvent *event) { controlWidget->hide(); @@ -599,6 +597,32 @@ void Plot::setMaxAndStart(int *buffer, size_t len, QRect plotRect) { gs_absVMax = (int)(gs_absVMax * 1.25 + 1); } +void Plot::appendMax(int *buffer, size_t len, QRect plotRect) { + if(len == 0) { + return; + } + + int vMin = INT_MAX, vMax = INT_MIN; + uint32_t sample_index = g_GraphStart ; + + for (; sample_index < len && xCoordOf(sample_index, plotRect) < plotRect.right() ; sample_index++) { + + int v = buffer[sample_index]; + if (v < vMin) vMin = v; + if (v > vMax) vMax = v; + } + + if (fabs((double) vMin) > gs_absVMax) { + gs_absVMax = (int)fabs((double) vMin); + } + + if (fabs((double) vMax) > gs_absVMax) { + gs_absVMax = (int)fabs((double) vMax); + } + + gs_absVMax = (int)(gs_absVMax * 1.25 + 1); +} + void Plot::PlotDemod(uint8_t *buffer, size_t len, QRect plotRect, QRect annotationRect, QPainter *painter, int graphNum, uint32_t plotOffset) { if (len == 0 || g_PlotGridX <= 0) { @@ -726,17 +750,160 @@ void Plot::PlotGraph(int *buffer, size_t len, QRect plotRect, QRect annotationRe //Graph annotations painter->drawPath(penPath); char str[200]; - snprintf(str, sizeof(str), "max=%d min=%d mean=%" PRId64 " n=%u/%zu CursorAVal=[%d] CursorBVal=[%d]" - , vMax - , vMin - , vMean - , g_GraphStop - g_GraphStart - , len - , buffer[CursorAPos] - , buffer[CursorBPos] + snprintf(str, sizeof(str), "max=%d min=%d mean=%" PRId64 " n=%u/%zu", + vMax, + vMin, + vMean, + g_GraphStop - g_GraphStart, + len + ); + + painter->drawText(20, annotationRect.bottom() - (48 - (12 * graphNum)), str); +} + +void Plot::drawAnnotations(QRect annotationRect, QPainter *painter) { + char *annotation; + uint32_t length = 0; + + // Make a tiny black box at the bottom of the plot window + QRect f(QPoint(80, annotationRect.bottom() - 59), QPoint(annotationRect.right(), annotationRect.bottom() - 74)); + painter->fillRect(f, BLACK); + + //Setup the scale string + char scalestr[20] = {0}; + + if (g_CursorScaleFactor != 1) { + if (g_CursorScaleFactorUnit[0] == '\x00') { + snprintf(scalestr, sizeof(scalestr), "[%2.2f] ", ((int32_t)(CursorBPos - CursorAPos)) / g_CursorScaleFactor); + } else { + snprintf(scalestr, sizeof(scalestr), "[%2.2f %s] ", ((int32_t)(CursorBPos - CursorAPos)) / g_CursorScaleFactor, g_CursorScaleFactorUnit); + } + } + + //Print the Graph Information + char graphText[] = "@%u..%u dt=%i %s zoom=%2.3f"; + length = ((sizeof(graphText))+(sizeof(uint32_t)*3)+sizeof(scalestr)+sizeof(float_t)); + + annotation = (char*)malloc(length); + memset(annotation, 0x00, length); + + snprintf(annotation, length, graphText, + g_GraphStart, + g_GraphStop, + CursorBPos - CursorAPos, + scalestr, + g_GraphPixelsPerPoint + ); + + painter->setPen(GREEN); + painter->drawText(82, annotationRect.bottom() - 62, annotation); + + //Print Grid Information if the grid is enabled + if(g_PlotGridX > 0) { + const char *gridLocked = (g_GridLocked ? "Locked" : "Unlocked"); + char gridText[] = "GridX=%lf GridY=%lf (%s) GridXoffset=%lf"; + length = (sizeof(gridText) + (sizeof(double)*3) + sizeof(gridLocked)); + + annotation = (char*)malloc(length); + memset(annotation, 0x00, length); + + snprintf(annotation, length, gridText, + g_PlotGridXdefault, + g_PlotGridYdefault, + gridLocked, + g_GridOffset ); - painter->drawText(20, annotationRect.bottom() - 23 - 20 * graphNum, str); + painter->setPen(WHITE); + painter->drawText(800, annotationRect.bottom() - 62, annotation); + } + + //Print the Cursor Information + char cursorText[] = "Cursor%s={Pos=%u Val=%d}"; + uint32_t pos = 0, loc = 375; + painter->setPen(WHITE); + + if(CursorAPos > 0) { + length = (sizeof(cursorText) + (sizeof(uint32_t)*3) + sizeof(" ") + 1); + pos = CursorAPos; + bool flag = false; + size_t value; + + annotation = (char*)malloc(length); + char *textA = (char*)malloc(length); + + memset(annotation, 0x00, length); + memset(textA, 0x00, length); + + strcat(textA, cursorText); + strcat(textA, " (%s%u)"); + + if(g_GraphBuffer[pos] <= g_OperationBuffer[pos]) { + flag = true; + value = (g_OperationBuffer[pos] - g_GraphBuffer[pos]); + } else { + value = (g_GraphBuffer[pos] - g_OperationBuffer[pos]); + } + + snprintf(annotation, length, textA, + "A", + pos, + g_GraphBuffer[pos], + flag ? "+" : "-", + value + ); + + painter->drawText(loc, annotationRect.bottom() - 48, annotation); + } + + if(CursorBPos > 0) { + length = ((sizeof(cursorText))+(sizeof(uint32_t)*2)+1); + pos = CursorBPos; + + annotation = (char*)malloc(length); + memset(annotation, 0x00, length); + + snprintf(annotation, length, cursorText, + "B", + pos, + g_GraphBuffer[pos] + ); + + painter->drawText(loc, annotationRect.bottom() - 36, annotation); + } + + if(g_CursorCPos > 0) { + length = ((sizeof(cursorText))+(sizeof(uint32_t)*2)+1); + pos = g_CursorCPos; + + annotation = (char*)malloc(length); + memset(annotation, 0x00, length); + + snprintf(annotation, length, cursorText, + "C", + pos, + g_GraphBuffer[pos] + ); + + painter->drawText(loc, annotationRect.bottom() - 24, annotation); + } + + if(g_CursorDPos > 0) { + length = ((sizeof(cursorText))+(sizeof(uint32_t)*2)+1); + pos = g_CursorDPos; + + annotation = (char*)malloc(length); + memset(annotation, 0x00, length); + + snprintf(annotation, length, cursorText, + "D", + pos, + g_GraphBuffer[pos] + ); + + painter->drawText(loc, annotationRect.bottom() - 12, annotation); + } + } void Plot::plotGridLines(QPainter *painter, QRect r) { @@ -787,24 +954,36 @@ void Plot::plotOperations(int *buffer, size_t len, QPainter *painter, QRect plot QPainterPath penPath; int32_t x = xCoordOf(g_GraphStart, plotRect), prevX = 0; int32_t y = yCoordOf(buffer[g_GraphStart], plotRect, gs_absVMax), prevY = 0; - int32_t current = 0; + int32_t current = 0, prev = 0; + bool changed = false; for (uint32_t pos = g_GraphStart; pos < len && xCoordOf(pos, plotRect) < plotRect.right(); pos++) { //Store the previous x and y values to move the pen to if we need to draw a line prevX = x; prevY = y; + changed = false; x = xCoordOf(pos, plotRect); + prev = current; current = buffer[pos]; y = yCoordOf(current, plotRect, gs_absVMax); //We only want to graph changes between the Graph Buffer and the Operation Buffer - if(current == g_GraphBuffer[pos]) continue; + if(current == g_GraphBuffer[pos]) { + //If this point is the same, but the last point is different, we want to plot that line + //as well + if((pos == 0) || (prev == g_GraphBuffer[pos - 1])) { + continue; + } + } else { + changed = true; + } penPath.moveTo(prevX, prevY); //Move the pen penPath.lineTo(x, y); //Draw the line from the previous coords to the new ones - if (g_GraphPixelsPerPoint > 10) { + //Only draw a white square if the point is different + if (g_GraphPixelsPerPoint > 10 && changed) { QRect point(QPoint(x - 3, y - 3), QPoint(x + 3, y + 3)); painter->fillRect(point, WHITE); } @@ -847,6 +1026,7 @@ void Plot::paintEvent(QPaintEvent *event) { //init graph variables setMaxAndStart(g_GraphBuffer, g_GraphTraceLen, plotRect); + appendMax(g_OperationBuffer, g_GraphTraceLen, plotRect); // center line int zeroHeight = plotRect.top() + (plotRect.bottom() - plotRect.top()) / 2; @@ -862,14 +1042,13 @@ void Plot::paintEvent(QPaintEvent *event) { } //Plot the Operation Overlay - //setMaxAndStart(g_OperationBuffer, g_GraphTraceLen, plotRect); plotOperations(g_OperationBuffer, g_GraphTraceLen, &painter, plotRect); //Plot the Overlay - if (gs_useOverlays) { + if (g_useOverlays) { //init graph variables - setMaxAndStart(s_OverlayBuff, g_GraphTraceLen, plotRect); - PlotGraph(s_OverlayBuff, g_GraphTraceLen, plotRect, infoRect, &painter, 1); + setMaxAndStart(g_OverlayBuffer, g_GraphTraceLen, plotRect); + PlotGraph(g_OverlayBuffer, g_GraphTraceLen, plotRect, infoRect, &painter, 1); } // End graph drawing @@ -895,31 +1074,7 @@ void Plot::paintEvent(QPaintEvent *event) { } //Draw annotations - char str[200]; - char scalestr[30] = {0}; - - if (g_CursorScaleFactor != 1) { - if (g_CursorScaleFactorUnit[0] == '\x00') { - snprintf(scalestr, sizeof(scalestr), "[%2.2f] ", ((int32_t)(CursorBPos - CursorAPos)) / g_CursorScaleFactor); - } else { - snprintf(scalestr, sizeof(scalestr), "[%2.2f %s] ", ((int32_t)(CursorBPos - CursorAPos)) / g_CursorScaleFactor, g_CursorScaleFactorUnit); - } - } - snprintf(str, sizeof(str), "@%u..%u dt=%i %szoom=%2.3f CursorAPos=%u CursorBPos=%u GridX=%lf GridY=%lf (%s) GridXoffset=%lf", - g_GraphStart, - g_GraphStop, - CursorBPos - CursorAPos, - scalestr, - g_GraphPixelsPerPoint, - CursorAPos, - CursorBPos, - g_PlotGridXdefault, - g_PlotGridYdefault, - g_GridLocked ? "Locked" : "Unlocked", - g_GridOffset - ); - painter.setPen(WHITE); - painter.drawText(20, infoRect.bottom() - 3, str); + drawAnnotations(infoRect, &painter); if (startMaxOld != startMax) { emit startMaxChanged(startMax); @@ -956,7 +1111,7 @@ Plot::Plot(QWidget *parent) : QWidget(parent), g_GraphPixelsPerPoint(1) { void Plot::closeEvent(QCloseEvent *event) { event->ignore(); this->hide(); - gs_useOverlays = false; + g_useOverlays = false; } // every 4 steps the zoom doubles (or halves) @@ -1283,6 +1438,26 @@ void Plot::keyPressEvent(QKeyEvent *event) { break; case Qt::Key_Equal: + if(event->modifiers() & Qt::ControlModifier) { + g_OperationBuffer[CursorAPos] += 5; + } else { + g_OperationBuffer[CursorAPos] += 1; + } + + RepaintGraphWindow(); + break; + + case Qt::Key_Minus: + if(event->modifiers() & Qt::ControlModifier) { + g_OperationBuffer[CursorAPos] -= 5; + } else { + g_OperationBuffer[CursorAPos] -= 1; + } + + RepaintGraphWindow(); + break; + + case Qt::Key_Plus: if(event->modifiers() & Qt::ControlModifier) { g_GraphBuffer[CursorAPos] += 5; } else { @@ -1292,7 +1467,7 @@ void Plot::keyPressEvent(QKeyEvent *event) { RepaintGraphWindow(); break; - case Qt::Key_Minus: + case Qt::Key_Underscore: if(event->modifiers() & Qt::ControlModifier) { g_GraphBuffer[CursorAPos] -= 5; } else { diff --git a/client/src/proxguiqt.h b/client/src/proxguiqt.h index 5fd739073..e19a43944 100644 --- a/client/src/proxguiqt.h +++ b/client/src/proxguiqt.h @@ -49,10 +49,12 @@ class Plot: public QWidget { void PlotDemod(uint8_t *buffer, size_t len, QRect plotRect, QRect annotationRect, QPainter *painter, int graphNum, uint32_t plotOffset); void plotGridLines(QPainter *painter, QRect r); void plotOperations(int *buffer, size_t len, QPainter *painter, QRect rect); + void drawAnnotations(QRect annotationRect, QPainter *painter); int xCoordOf(int i, QRect r); int yCoordOf(int v, QRect r, int maxVal); int valueOf_yCoord(int y, QRect r, int maxVal); void setMaxAndStart(int *buffer, size_t len, QRect plotRect); + void appendMax(int *buffer, size_t len, QRect plotRect); QColor getColor(int graphNum); public: