Splitting display works
This commit is contained in:
parent
aa2c74f4e1
commit
ce255f9856
2
Makefile
2
Makefile
@ -1,4 +1,4 @@
|
|||||||
TARGET = qtimer
|
TARGET = quest
|
||||||
LIBS = -lm -luiohook
|
LIBS = -lm -luiohook
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -g -Wall
|
CFLAGS = -g -Wall
|
||||||
|
22
display.c
22
display.c
@ -1,5 +1,14 @@
|
|||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
|
||||||
|
const char *millitime = "%8d.%d";
|
||||||
|
const char *secondstime = "%7d.%02d";
|
||||||
|
const char *minutestime = "%7d:%02d";
|
||||||
|
const char *hourstime = "%5d:%02d:%02d";
|
||||||
|
const char *fulltime = "%2d:%02d:%02d.%02d";
|
||||||
|
const char *sfulltime = "%4d:%02d.%02d";
|
||||||
|
|
||||||
|
struct termios base;
|
||||||
|
|
||||||
void setBGColor(struct color c)
|
void setBGColor(struct color c)
|
||||||
{
|
{
|
||||||
printf("\033[48;2;%d;%d;%dm", c.r, c.g, c.b);
|
printf("\033[48;2;%d;%d;%dm", c.r, c.g, c.b);
|
||||||
@ -37,6 +46,11 @@ void stdBuffer()
|
|||||||
|
|
||||||
void initScreen(struct color bg, struct color fg)
|
void initScreen(struct color bg, struct color fg)
|
||||||
{
|
{
|
||||||
|
struct termios t;
|
||||||
|
tcgetattr(1, &base);
|
||||||
|
t = base;
|
||||||
|
t.c_lflag &= (~ECHO & ~ICANON);
|
||||||
|
tcsetattr(1, TCSANOW, &t);
|
||||||
altBuffer();
|
altBuffer();
|
||||||
setBGColor(bg);
|
setBGColor(bg);
|
||||||
setFGColor(fg);
|
setFGColor(fg);
|
||||||
@ -46,6 +60,7 @@ void initScreen(struct color bg, struct color fg)
|
|||||||
|
|
||||||
void resetScreen()
|
void resetScreen()
|
||||||
{
|
{
|
||||||
|
tcsetattr(1, TCSANOW, &base);
|
||||||
clrScreen();
|
clrScreen();
|
||||||
enableCursor();
|
enableCursor();
|
||||||
stdBuffer();
|
stdBuffer();
|
||||||
@ -68,3 +83,10 @@ void rghtPrint(int row, int maxlen, char* text)
|
|||||||
else
|
else
|
||||||
printf("\033[%d;1H%.*s", row, maxlen, text);
|
printf("\033[%d;1H%.*s", row, maxlen, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawHLine(int row, int maxlen)
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= maxlen; i++) {
|
||||||
|
printf("\033[%d;%dH─", row, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
10
display.h
10
display.h
@ -1,5 +1,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
extern const char *millitime;
|
||||||
|
extern const char *secondstime;
|
||||||
|
extern const char *minutestime;
|
||||||
|
extern const char *hourstime;
|
||||||
|
extern const char *fulltime;
|
||||||
|
extern const char *sfulltime;
|
||||||
|
|
||||||
struct color {
|
struct color {
|
||||||
int r;
|
int r;
|
||||||
@ -19,3 +27,5 @@ void resetScreen();
|
|||||||
void cntrPrint(int row, int col, int maxlen, char *text);
|
void cntrPrint(int row, int col, int maxlen, char *text);
|
||||||
void leftPrint(int row, int maxlen, char *text);
|
void leftPrint(int row, int maxlen, char *text);
|
||||||
void rghtPrint(int row, int maxlem, char *text);
|
void rghtPrint(int row, int maxlem, char *text);
|
||||||
|
void drawHLine(int row, int maxlen);
|
||||||
|
|
||||||
|
157
timer.c
157
timer.c
@ -1,22 +1,35 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
//Timekeeping
|
||||||
|
struct timespec timestart, finish;
|
||||||
|
int currentMS = 0;
|
||||||
|
bool timerActive;
|
||||||
|
|
||||||
|
//Global hotkeys
|
||||||
char buf;
|
char buf;
|
||||||
int pipefd[2];
|
int pipefd[2];
|
||||||
struct timespec timestart, finish;
|
|
||||||
struct keymap km;
|
struct keymap km;
|
||||||
int h, w;
|
|
||||||
char *gameTitle = "title not loaded";
|
|
||||||
char *categoryTitle = "category not loaded";
|
|
||||||
int attempts = 0;
|
|
||||||
|
|
||||||
bool timerActive;
|
//UI
|
||||||
struct segment *segments;
|
int h, w;
|
||||||
int segmentCount;
|
|
||||||
int currentSegment = 0;
|
|
||||||
char currentTime[10];
|
|
||||||
int deltasEnabled = 1;
|
int deltasEnabled = 1;
|
||||||
int sgmtdurEnabled = 1;
|
int sgmtdurEnabled = 1;
|
||||||
int pbEnabled = 1;
|
int pbEnabled = 1;
|
||||||
|
bool resized = false;
|
||||||
|
|
||||||
|
//Run data
|
||||||
|
const char *schemaver = "v1.0.1";
|
||||||
|
const char *timersname = "quest";
|
||||||
|
const char *timerlname = "Quinn's Utterly Elegant Speedrun Timer";
|
||||||
|
const char *timerver = "v0.4.0";
|
||||||
|
const char *timerlink = "https://github.com/SilentFungus/quest";
|
||||||
|
char *gameTitle = "title not loaded";
|
||||||
|
char *categoryTitle = "category not loaded";
|
||||||
|
int attempts = 0;
|
||||||
|
struct segment *segments;
|
||||||
|
int segmentCount;
|
||||||
|
int currentSegment = -1;
|
||||||
|
char currentTime[10];
|
||||||
|
|
||||||
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td)
|
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec* td)
|
||||||
{
|
{
|
||||||
@ -87,6 +100,7 @@ void start()
|
|||||||
return;
|
return;
|
||||||
clock_gettime(CLOCK_REALTIME, ×tart);
|
clock_gettime(CLOCK_REALTIME, ×tart);
|
||||||
timerActive = true;
|
timerActive = true;
|
||||||
|
currentSegment = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop()
|
void stop()
|
||||||
@ -94,10 +108,18 @@ void stop()
|
|||||||
if (!timerActive)
|
if (!timerActive)
|
||||||
return;
|
return;
|
||||||
timerActive = false;
|
timerActive = false;
|
||||||
|
currentSegment = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void split()
|
void split()
|
||||||
{
|
{
|
||||||
|
if (!timerActive)
|
||||||
|
return;
|
||||||
|
segments[currentSegment].realtimeMS = currentMS;
|
||||||
|
segments[currentSegment].gametimeMS = currentMS;
|
||||||
|
currentSegment++;
|
||||||
|
if (currentSegment >= segmentCount)
|
||||||
|
stop();
|
||||||
/*
|
/*
|
||||||
struct timespec *temp = malloc(sizeof(struct timespec) * (splitCount + 1));
|
struct timespec *temp = malloc(sizeof(struct timespec) * (splitCount + 1));
|
||||||
for (int i = 0; i < splitCount; i++) {
|
for (int i = 0; i < splitCount; i++) {
|
||||||
@ -149,22 +171,34 @@ void loadKeymap()
|
|||||||
//fclose(fp);
|
//fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawHLine(int row)
|
void ftime(char *timestr, bool withMS, int ms)
|
||||||
{
|
{
|
||||||
for (int i = 0; i <= w; i++)
|
int seconds = ms / 1000;
|
||||||
printf("\033[%d;%dH─", row, i);
|
int minutes = seconds / 60;
|
||||||
}
|
int hours = minutes / 60;
|
||||||
|
//A few better formatted variables for displaying these numbers
|
||||||
|
int tms = (ms % 1000) / 10;
|
||||||
|
int oms = tms / 10;
|
||||||
|
int s = seconds % 60;
|
||||||
|
int m = minutes % 60;
|
||||||
|
int h = hours;
|
||||||
|
|
||||||
int ftime(char *timestr, int ms)
|
if (hours) {
|
||||||
{
|
if (withMS)
|
||||||
int displayMS = (ms % 1000) / 10;
|
sprintf(timestr, fulltime, h, abs(h), abs(m), abs(s), abs(tms));
|
||||||
int seconds = ms / 1000;
|
else
|
||||||
int minutes = seconds / 60;
|
sprintf(timestr, hourstime, h, abs(m), abs(s));
|
||||||
if (minutes)
|
} else if (minutes) {
|
||||||
sprintf(timestr, "%2d:%02d.%02d", minutes, seconds % 60, displayMS);
|
if (withMS)
|
||||||
else
|
sprintf(timestr, sfulltime, m, abs(s), abs(tms));
|
||||||
sprintf(timestr, "%2d.%02d", seconds % 60, displayMS);
|
else
|
||||||
return 0;
|
sprintf(timestr, minutestime, m, abs(s));
|
||||||
|
} else {
|
||||||
|
if (withMS)
|
||||||
|
sprintf(timestr, secondstime, s, abs(tms));
|
||||||
|
else
|
||||||
|
sprintf(timestr, millitime, s, abs(oms));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int timespecToMS(struct timespec t)
|
int timespecToMS(struct timespec t)
|
||||||
@ -177,23 +211,63 @@ int timespecToMS(struct timespec t)
|
|||||||
void drawSegments()
|
void drawSegments()
|
||||||
{
|
{
|
||||||
char data[(deltasEnabled * 10) + (sgmtdurEnabled * 10) + (pbEnabled * 10) + 11];
|
char data[(deltasEnabled * 10) + (sgmtdurEnabled * 10) + (pbEnabled * 10) + 11];
|
||||||
char segmentTime[10];
|
char segmentTime[11];
|
||||||
char zeroStr[10];
|
char zeroStr[11];
|
||||||
ftime(zeroStr, 0);
|
char deltaTime[11];
|
||||||
|
char sgmtTime[11];
|
||||||
|
char segTime[11];
|
||||||
|
ftime(zeroStr, false, 0);
|
||||||
for(int i = 0; i < segmentCount; i++) {
|
for(int i = 0; i < segmentCount; i++) {
|
||||||
if (!ftime(segmentTime, segments[i].realtimeMS)) {
|
ftime(segmentTime, true, segments[i].pbrealtimeMS);
|
||||||
|
if (i >= currentSegment) {
|
||||||
sprintf(data, "%10s%10s%10s%10s", zeroStr, zeroStr, zeroStr, segmentTime);
|
sprintf(data, "%10s%10s%10s%10s", zeroStr, zeroStr, zeroStr, segmentTime);
|
||||||
} else {
|
} else {
|
||||||
sprintf(data, "%s", "Failed to format time");
|
ftime(deltaTime, false, segments[i].realtimeMS - segments[i].pbrealtimeMS);
|
||||||
|
ftime(sgmtTime, false, segments[i].realtimeMS - segments[i - 1].realtimeMS);
|
||||||
|
ftime(segTime, false, segments[i].realtimeMS);
|
||||||
|
sprintf(data, "%10s%10s%10s%10s", deltaTime, sgmtTime, segTime, segmentTime);
|
||||||
}
|
}
|
||||||
rghtPrint(6 + i, w, data);
|
rghtPrint(6 + i, w, data);
|
||||||
leftPrint(6 + i, w, segments[i].name);
|
leftPrint(6 + i, w, segments[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawCurrentSegment()
|
||||||
|
{
|
||||||
|
char data[(deltasEnabled * 10) + (sgmtdurEnabled * 10) + (pbEnabled * 10) + 11];
|
||||||
|
strcpy(data, "");
|
||||||
|
char pbTime[11];
|
||||||
|
char deltaTime[11];
|
||||||
|
char sgmtTime[11];
|
||||||
|
char segTime[11];
|
||||||
|
if (deltasEnabled) {
|
||||||
|
ftime(deltaTime, false, currentMS - segments[currentSegment].pbrealtimeMS);
|
||||||
|
strcat(data, deltaTime);
|
||||||
|
}
|
||||||
|
if (sgmtdurEnabled) {
|
||||||
|
if (currentSegment == 0)
|
||||||
|
ftime(sgmtTime, false, currentMS);
|
||||||
|
else
|
||||||
|
ftime(sgmtTime, false, currentMS - segments[currentSegment - 1].realtimeMS);
|
||||||
|
strcat(data, sgmtTime);
|
||||||
|
}
|
||||||
|
ftime(segTime, false, currentMS);
|
||||||
|
strcat(data, segTime);
|
||||||
|
if (pbEnabled) {
|
||||||
|
ftime(pbTime, true, segments[currentSegment].pbrealtimeMS);
|
||||||
|
strcat(data, pbTime);
|
||||||
|
}
|
||||||
|
data[(deltasEnabled * 10) + (sgmtdurEnabled * 10) + (pbEnabled * 10) + 11] = '\0';
|
||||||
|
rghtPrint(6 + currentSegment, w, data);
|
||||||
|
leftPrint(6 + currentSegment, w, segments[currentSegment].name);
|
||||||
|
}
|
||||||
|
|
||||||
void drawDisplay()
|
void drawDisplay()
|
||||||
{
|
{
|
||||||
clrScreen();
|
if (resized) {
|
||||||
|
clrScreen();
|
||||||
|
resized = false;
|
||||||
|
}
|
||||||
rghtPrint(1, w, "Attempts");
|
rghtPrint(1, w, "Attempts");
|
||||||
char atmpt[10];
|
char atmpt[10];
|
||||||
sprintf(atmpt, "%9d", attempts);
|
sprintf(atmpt, "%9d", attempts);
|
||||||
@ -203,13 +277,17 @@ void drawDisplay()
|
|||||||
char cols[41];
|
char cols[41];
|
||||||
sprintf(cols, "%10s%10s%10s%10s", "Delta", "Sgmt", "Time", "PB");
|
sprintf(cols, "%10s%10s%10s%10s", "Delta", "Sgmt", "Time", "PB");
|
||||||
rghtPrint(4, w, cols);
|
rghtPrint(4, w, cols);
|
||||||
drawHLine(5);
|
drawHLine(5, w);
|
||||||
printf("\033[5;%dH[dsp]", 2);
|
printf("\033[5;3H[dsp]");
|
||||||
drawSegments();
|
drawSegments();
|
||||||
drawHLine(segmentCount + 6);
|
if (timerActive) {
|
||||||
struct timespec delta;
|
drawCurrentSegment();
|
||||||
sub_timespec(timestart, finish, &delta);
|
struct timespec delta;
|
||||||
ftime(currentTime, timespecToMS(delta));
|
sub_timespec(timestart, finish, &delta);
|
||||||
|
currentMS = timespecToMS(delta);
|
||||||
|
}
|
||||||
|
drawHLine(segmentCount + 6, w);
|
||||||
|
ftime(currentTime, true, currentMS);
|
||||||
rghtPrint(segmentCount + 7, w, currentTime);
|
rghtPrint(segmentCount + 7, w, currentTime);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@ -220,6 +298,7 @@ void resize(int i)
|
|||||||
ioctl(1, TIOCGWINSZ, &ws);
|
ioctl(1, TIOCGWINSZ, &ws);
|
||||||
w = ws.ws_col;
|
w = ws.ws_col;
|
||||||
h = ws.ws_row;
|
h = ws.ws_row;
|
||||||
|
resized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadFile(char *path)
|
void loadFile(char *path)
|
||||||
@ -287,9 +366,9 @@ void loadFile(char *path)
|
|||||||
cJSON *time = cJSON_GetObjectItemCaseSensitive(segtime, "realtimeMS");
|
cJSON *time = cJSON_GetObjectItemCaseSensitive(segtime, "realtimeMS");
|
||||||
cJSON *gtime = cJSON_GetObjectItemCaseSensitive(segtime, "gametimeMS");
|
cJSON *gtime = cJSON_GetObjectItemCaseSensitive(segtime, "gametimeMS");
|
||||||
if (cJSON_IsNumber(time))
|
if (cJSON_IsNumber(time))
|
||||||
segments[it].realtimeMS = time->valueint;
|
segments[it].pbrealtimeMS = time->valueint;
|
||||||
if (cJSON_IsNumber(gtime))
|
if (cJSON_IsNumber(gtime))
|
||||||
segments[it].gametimeMS = gtime->valueint;
|
segments[it].pbgametimeMS = gtime->valueint;
|
||||||
}
|
}
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
@ -327,7 +406,7 @@ int main(int argc, char **argv)
|
|||||||
if (timerActive) {
|
if (timerActive) {
|
||||||
clock_gettime(CLOCK_REALTIME, &finish);
|
clock_gettime(CLOCK_REALTIME, &finish);
|
||||||
}
|
}
|
||||||
usleep(4000);
|
usleep(5000);
|
||||||
}
|
}
|
||||||
resetScreen();
|
resetScreen();
|
||||||
kill(cpid, SIGTERM);
|
kill(cpid, SIGTERM);
|
||||||
|
6
timer.h
6
timer.h
@ -37,6 +37,8 @@ struct segment
|
|||||||
char *name;
|
char *name;
|
||||||
int realtimeMS;
|
int realtimeMS;
|
||||||
int gametimeMS;
|
int gametimeMS;
|
||||||
|
int pbrealtimeMS;
|
||||||
|
int pbgametimeMS;
|
||||||
bool isSkipped;
|
bool isSkipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,10 +52,10 @@ void stop();
|
|||||||
void split();
|
void split();
|
||||||
void tpause();
|
void tpause();
|
||||||
void loadKeymap();
|
void loadKeymap();
|
||||||
void drawHLine(int row);
|
void ftime(char *timestr, bool withMS, int ms);
|
||||||
int ftime(char *timestr, int ms);
|
|
||||||
int timespecToMS(struct timespec t);
|
int timespecToMS(struct timespec t);
|
||||||
void drawSegments();
|
void drawSegments();
|
||||||
|
void drawCurrentSegment();
|
||||||
void drawDisplay();
|
void drawDisplay();
|
||||||
void resize(int i);
|
void resize(int i);
|
||||||
void loadFile(char *path);
|
void loadFile(char *path);
|
||||||
|
Loading…
Reference in New Issue
Block a user