Improved decoding and screen presentation (especially the scroll region at the bottom).
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <timeapi.h>
|
||||
#include "SerialPort\SerialPort.h"
|
||||
|
||||
enum
|
||||
@@ -21,6 +22,8 @@ CSerialPort avr;
|
||||
int avrOnPort = COM_NO_PORT; // Serial Port 1, 2, ... taking note that some USB adapters can be up toward channel 11, 12, ...
|
||||
unsigned avrBaud = 9600;
|
||||
|
||||
DWORD const retryInterval = 1000; // ms
|
||||
|
||||
// Each DT is the hex-character from the stream
|
||||
//
|
||||
//
|
||||
@@ -234,36 +237,92 @@ char progname[MAXTEXTLEN];
|
||||
|
||||
int AttachToSerialPort();
|
||||
int DetachSerialPort();
|
||||
void ProcessSerialReceive(void);
|
||||
|
||||
// SerialSend
|
||||
//
|
||||
// Try to send the message.
|
||||
//
|
||||
// @param[in] p is a pointer to the message to send
|
||||
// @param[in] len is the count of bytes in the message
|
||||
// @returns true if the serial interface accepted it.
|
||||
//
|
||||
bool SerialSend(const uint8_t *p, DWORD len);
|
||||
|
||||
#define SERIALQUEUESIZE 3
|
||||
typedef struct {
|
||||
uint8_t *messageToSend;
|
||||
DWORD len;
|
||||
} SerialQueue_T;
|
||||
|
||||
static SerialQueue_T serialQueue[SERIALQUEUESIZE];
|
||||
static int serialQueueCount = 0;
|
||||
|
||||
|
||||
// ProcessSerialQueue
|
||||
//
|
||||
// If there are parameters passed, insert a message into the queue.
|
||||
// Process the queue (with zero or more messages) to send
|
||||
//
|
||||
// @param[in] p is a pointer to the message to send
|
||||
// @param[in] len is the count of bytes in the message
|
||||
// @returns false if the queue (which is a fixed size) is full.
|
||||
//
|
||||
bool ProcessSerialQueue(const uint8_t *p = NULL, DWORD len = 0);
|
||||
|
||||
|
||||
// ProcessSerialReceive
|
||||
//
|
||||
// See if anything came in, and if so, process it.
|
||||
//
|
||||
// @returns true if a message was processed.
|
||||
//
|
||||
bool ProcessSerialReceive(void);
|
||||
void EnumerateComPorts();
|
||||
unsigned long Hex2Dec(uint8_t *p, int dig);
|
||||
|
||||
bool UserWantsToExitCanSniff = false;
|
||||
|
||||
DWORD progStartTime;
|
||||
|
||||
// For special cursor positioning
|
||||
bool consoleInit = false;
|
||||
HANDLE hStdout, hStdin;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
WORD wOldColorAttrs; // Save the current console colors
|
||||
|
||||
short consoleWidth = 105;
|
||||
short consoleHeight = 70;
|
||||
short consoleScrollHeight = 14;
|
||||
// 0 99
|
||||
// +---------------------------------------------------------------+
|
||||
// | Program banner information | 0
|
||||
// | on two lines |
|
||||
// | Current status information starts on line 3 |
|
||||
// | and down a ways... |
|
||||
// | |
|
||||
// | |
|
||||
// | |
|
||||
// + Down near the bottom is the scroll region + 69
|
||||
// | |
|
||||
// | | 79
|
||||
// +---------------------------------------------------------------+
|
||||
const int scrollTop = 59;
|
||||
const int scrollBot = 69;
|
||||
|
||||
|
||||
void Console_Init();
|
||||
void Console_Cls();
|
||||
void Console_SetCursor(short x, short y);
|
||||
void Console_Write(char *text);
|
||||
void Console_WriteAt(short x, short y, char *text);
|
||||
void Console_Write(const char *text);
|
||||
void Console_WriteAt(short x, short y, const char *text);
|
||||
void Console_ScrollBottomRegion(short topLine, short bottomLine);
|
||||
bool Console_AdvanceToNextLineIfNotRoomFor(short x, int scroll = -1);
|
||||
|
||||
uint8_t LastSentMessage[MAXTEXTLEN];
|
||||
uint16_t LastSentMessageLen;
|
||||
uint64_t LastSentMessageTime; // when the last message was sent
|
||||
|
||||
typedef struct {
|
||||
const char Char;
|
||||
const char *pDescription;
|
||||
const char *pCommand;
|
||||
int cmdLen;
|
||||
DWORD cmdLen;
|
||||
} UserCmd_T;
|
||||
|
||||
const UserCmd_T UserCommands[] = {
|
||||
@@ -324,21 +383,26 @@ void ProcessWindowsMessage(void) {
|
||||
// EmitBuffer
|
||||
//
|
||||
// Emits the provided buffer to the console, translating non-printable
|
||||
// characters into hex codes enclosed in angle brackets.
|
||||
// characters into hex codes enclosed in square brackets.
|
||||
//
|
||||
// Consider line-wrapping to align the next line
|
||||
//
|
||||
void EmitBuffer(const char *prefix, const uint8_t *buf, bool appendReturn = false) {
|
||||
void EmitBuffer(const char *prefix, const uint8_t *buf, size_t len = 0, bool appendReturn = false) {
|
||||
int i = 0;
|
||||
const char *p = (const char *)buf;
|
||||
printf("[%3d]%s", (int)strlen(p), prefix);
|
||||
while (*p) {
|
||||
DWORD now = timeGetTime();
|
||||
char txtBuf[MAXTEXTLEN] = "";
|
||||
|
||||
if (len == 0) len = strlen((const char *)buf);
|
||||
sprintf_s(txtBuf, MAXTEXTLEN, "%7.3f: [%3d]%s", (float)(now - progStartTime)/1000.0f, (int)strlen(p), prefix);
|
||||
Console_Write(txtBuf);
|
||||
while (*p && ((unsigned)(p - (const char *)buf) < len)) {
|
||||
if (isprint(*p)) {
|
||||
putchar(*p);
|
||||
i++;
|
||||
} else if (*p == '\r') {
|
||||
putchar('\n');
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
} else if (*p == '\n') {
|
||||
// skip it
|
||||
} else {
|
||||
@@ -346,7 +410,8 @@ void EmitBuffer(const char *prefix, const uint8_t *buf, bool appendReturn = fals
|
||||
}
|
||||
if ((i & 3) == 0) {
|
||||
if (Console_AdvanceToNextLineIfNotRoomFor(12, 1)) {
|
||||
printf(" ");
|
||||
//Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
printf(" "); // sized to get past the timestamp, length, and prefix
|
||||
i = 0;
|
||||
} else {
|
||||
printf(" ");
|
||||
@@ -355,34 +420,64 @@ void EmitBuffer(const char *prefix, const uint8_t *buf, bool appendReturn = fals
|
||||
p++;
|
||||
}
|
||||
if (appendReturn) {
|
||||
putch('\r');
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot); // putch('\r');
|
||||
} else {
|
||||
putch('\n');
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
//putch('\n');
|
||||
//Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EchoSerialRecv(const uint8_t *pMsg) {
|
||||
Console_SetCursor(0, -3);
|
||||
Console_SetCursor(0, -1);
|
||||
EmitBuffer("< ", pMsg);
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
}
|
||||
|
||||
void SerialSend(const uint8_t *p, int len) {
|
||||
Console_SetCursor(0, -3);
|
||||
EmitBuffer("> ", p);
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
if (avr.Write((const LPVOID)p, len) != len) {
|
||||
Console_SetCursor(0, -3);
|
||||
Console_Write("***** Failed to send. Port not open?");
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
bool SerialSend(const uint8_t *p, DWORD len) {
|
||||
bool retVal = false;
|
||||
Console_SetCursor(0, -1);
|
||||
EmitBuffer("> ", p, len);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
if (avr.Write((const LPVOID)p, len) == len) {
|
||||
retVal = true;
|
||||
} else {
|
||||
// If we send something, we expect a response within ?200ms? and if not we should try again, up to 5 times.
|
||||
memcpy(LastSentMessage, p, len);
|
||||
LastSentMessageTime = GetTickCount64();
|
||||
LastSentMessageLen = len;
|
||||
Console_SetCursor(0, -1);
|
||||
Console_Write("***** Failed to send. Port not open?");
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool ProcessSerialQueue(const uint8_t *p, DWORD len) {
|
||||
bool retVal = false; // assume fail
|
||||
static bool freshData = false;
|
||||
//DWORD now = timeGetTime();
|
||||
//static DWORD lastSendTime = timeGetTime();
|
||||
|
||||
if (p && len) {
|
||||
if (serialQueueCount < SERIALQUEUESIZE) {
|
||||
serialQueue[serialQueueCount].messageToSend = (uint8_t *)malloc(len);
|
||||
if (serialQueue[serialQueueCount].messageToSend) {
|
||||
memcpy(serialQueue[serialQueueCount].messageToSend, p, len);
|
||||
serialQueue[serialQueueCount].len = len;
|
||||
serialQueueCount++;
|
||||
retVal = true;
|
||||
freshData = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (serialQueueCount) {
|
||||
if (SerialSend((const uint8_t *)serialQueue[0].messageToSend, serialQueue[0].len)) {
|
||||
--serialQueueCount;
|
||||
free(serialQueue[0].messageToSend);
|
||||
for (int i = 0; i < serialQueueCount; i++) {
|
||||
serialQueue[i] = serialQueue[i + 1];
|
||||
}
|
||||
retVal = true;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@@ -412,13 +507,13 @@ void EmitRuntimeHelp() {
|
||||
Console_Write(buf);
|
||||
}
|
||||
if (avr.IsOpen()) {
|
||||
Console_SetCursor(0, -3);
|
||||
Console_SetCursor(0, -1);
|
||||
printf(" Com Status: RTS: %-3s ", avr.Get_RTS_State() ? "ON" : "OFF");
|
||||
printf("DTR: %-3s ", avr.Get_DTR_State() ? "ON" : "OFF");
|
||||
printf("CTS: %-3s ", avr.Get_CTS_State() ? "ON" : "OFF");
|
||||
printf("DSR: %-3s ", avr.Get_DSR_State() ? "ON" : "OFF");
|
||||
printf("RI: %-3s\n", avr.Get_RI_State() ? "ON" : "OFF");
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,8 +545,8 @@ static void PCMessage(const char *msg, int len, uint8_t **src, const char * (fnc
|
||||
msg,
|
||||
p
|
||||
);
|
||||
Console_AdvanceToNextLineIfNotRoomFor(26);
|
||||
Console_Write(outBuf);
|
||||
Console_AdvanceToNextLineIfNotRoomFor(28);
|
||||
}
|
||||
|
||||
|
||||
@@ -491,6 +586,75 @@ const char * InputText(uint32_t val) {
|
||||
}
|
||||
}
|
||||
|
||||
const char *ProgramName(uint8_t val) {
|
||||
val &= 0x7F; // Not accommodating the other variants yet
|
||||
const char *nameList[] = {
|
||||
"Hall A(HALL1)",
|
||||
"Hall B",
|
||||
"Hall C",
|
||||
"unk",
|
||||
"Hall C",
|
||||
"Hall E",
|
||||
"Live Concert",
|
||||
"unk",
|
||||
"Tokyo",
|
||||
"Freiburg",
|
||||
"Royaumont",
|
||||
"unk",
|
||||
"Village Gate",
|
||||
"Village Vanguard",
|
||||
"The Bottom Line",
|
||||
"unk",
|
||||
"The Roxy Theater",
|
||||
"Warehouse Loft",
|
||||
"Arena",
|
||||
"unk",
|
||||
"Disco",
|
||||
"Party",
|
||||
"Game",
|
||||
"6 / 8CH Stereo",
|
||||
"Pop / Rock",
|
||||
"DJ",
|
||||
"unk",
|
||||
"unk",
|
||||
"Opera",
|
||||
"Pavillion",
|
||||
"unk",
|
||||
"unk",
|
||||
"Mono Movie",
|
||||
"Variety Sports",
|
||||
"unk",
|
||||
"unk",
|
||||
"Spectacre",
|
||||
"Sci - Fi",
|
||||
"unk",
|
||||
"unk",
|
||||
"Adventure",
|
||||
"General",
|
||||
"unk",
|
||||
"unk",
|
||||
"Normal",
|
||||
"Enhanced",
|
||||
"unk",
|
||||
"unk",
|
||||
"PLII Movie",
|
||||
"PLII Music",
|
||||
"Neo: 6 Movie",
|
||||
"Neo: 6 Music",
|
||||
"STEREO A 2CH Stereo",
|
||||
"STEREO B 2CH Direct Stereo"
|
||||
"THX A Cinema",
|
||||
"THX B Music",
|
||||
};
|
||||
if (val < sizeof(nameList)) {
|
||||
return nameList[val];
|
||||
} else {
|
||||
return "huh?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// VolumeDB
|
||||
//
|
||||
// Convert the communication units of volume into db
|
||||
@@ -521,7 +685,7 @@ const char *VolumeDB(uint32_t val) {
|
||||
|
||||
void ShowAll(void) {
|
||||
if (avrStatus.headerValid) {
|
||||
Console_SetCursor(0, 3);
|
||||
Console_SetCursor(0, 2);
|
||||
char buf[MAXTEXTLEN];
|
||||
sprintf_s(buf, MAXTEXTLEN, "Model ID: %c%c%c%c%c, ver: %c\n", avrStatus.header.type[0], avrStatus.header.type[1],
|
||||
avrStatus.header.type[2], avrStatus.header.type[3], avrStatus.header.type[4],
|
||||
@@ -637,7 +801,7 @@ void ProcessKeyboard(void) {
|
||||
static uint32_t spin = 0;
|
||||
bool cmdFound = false;
|
||||
|
||||
Console_SetCursor(0, -3);
|
||||
Console_SetCursor(0, -1);
|
||||
if (spin++ % 16 == 0)
|
||||
EmitSpinner();
|
||||
if (CS_KeyHit()) {
|
||||
@@ -654,28 +818,28 @@ void ProcessKeyboard(void) {
|
||||
break;
|
||||
case 'S':
|
||||
avr.Set_RTS_State(TRUE);
|
||||
Console_SetCursor(0, -3);
|
||||
Console_SetCursor(0, -1);
|
||||
printf("RTS set ON\n");
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
break;
|
||||
case 's':
|
||||
avr.Set_RTS_State(FALSE);
|
||||
Console_SetCursor(0, -3);
|
||||
Console_SetCursor(0, -1);
|
||||
printf("RTS set OFF\n");
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < sizeof(UserCommands) / sizeof(UserCmd_T); i++) {
|
||||
if (UserCommands[i].Char == c) {
|
||||
SerialSend((const uint8_t *)UserCommands[i].pCommand, UserCommands[i].cmdLen);
|
||||
ProcessSerialQueue((const uint8_t *)UserCommands[i].pCommand, UserCommands[i].cmdLen);
|
||||
cmdFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cmdFound) {
|
||||
Console_SetCursor(0, -3);
|
||||
Console_SetCursor(0, -1);
|
||||
printf("Unrecognized command '%c' (0x%02X)\n", isprint(c) ? c : '.', (unsigned char)c);
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -699,7 +863,7 @@ void GetProgName(char *name) {
|
||||
}
|
||||
|
||||
|
||||
void EmitHelp() {
|
||||
void EmitCommandLineHelp() {
|
||||
printf("%s [options] by Smartware Computing\n", progname);
|
||||
printf(" options:\n");
|
||||
printf(" -C=X[,yyyy] Set to Com port X to baud rate yyyy\n");
|
||||
@@ -718,6 +882,7 @@ void EmitHelp() {
|
||||
/******************************************************/
|
||||
|
||||
int __cdecl main(int argc, char *argv[]) {
|
||||
progStartTime = timeGetTime();
|
||||
Console_Init();
|
||||
|
||||
GetProgName(argv[0]);
|
||||
@@ -732,12 +897,12 @@ int __cdecl main(int argc, char *argv[]) {
|
||||
avrBaud = param2;
|
||||
} else {
|
||||
printf("***** Unrecognized command '%s' *****\n", argv[i]);
|
||||
EmitHelp();
|
||||
EmitCommandLineHelp();
|
||||
exit(EXIT_IllegalOption);
|
||||
}
|
||||
}
|
||||
if (argc == 0 || avrOnPort == COM_NO_PORT) {
|
||||
EmitHelp();
|
||||
EmitCommandLineHelp();
|
||||
}
|
||||
|
||||
Console_Cls();
|
||||
@@ -750,7 +915,8 @@ int __cdecl main(int argc, char *argv[]) {
|
||||
printf("Attached to Serial Port on COM%i at %i baud\n", avrOnPort, avrBaud);
|
||||
do {
|
||||
ProcessKeyboard();
|
||||
ProcessSerialReceive();
|
||||
/* bool anyRcvdMsg = */ ProcessSerialReceive();
|
||||
ProcessSerialQueue();
|
||||
ProcessWindowsMessage();
|
||||
} while (!UserWantsToExitCanSniff);
|
||||
DetachSerialPort();
|
||||
@@ -815,14 +981,23 @@ void ProcessResponse(uint8_t type, uint8_t guard, uint16_t cmd, uint16_t data) {
|
||||
char buf[MAXTEXTLEN];
|
||||
switch (cmd) {
|
||||
case 0x26:
|
||||
sprintf_s(buf, MAXTEXTLEN, "Vol: %s", VolumeDB(data));
|
||||
sprintf_s(buf, MAXTEXTLEN, "Vol: %s\n", VolumeDB(data));
|
||||
SetData(&avrStatus.config.DT15, Dec2Hex(data, 2));
|
||||
Console_Write(buf);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
ShowAll();
|
||||
break;
|
||||
case 0x28:
|
||||
sprintf_s(buf, MAXTEXTLEN, "Prog: %s\n", ProgramName(data));
|
||||
SetData(&avrStatus.config.DT19, Dec2Hex(data, 2));
|
||||
Console_Write(buf);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
ShowAll();
|
||||
break;
|
||||
default:
|
||||
sprintf_s(buf, MAXTEXTLEN, "type: %X, guard: %X, cmd: %02X, data: %02X", type, guard, cmd, data);
|
||||
Console_Write(buf);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -902,7 +1077,8 @@ void AnalyzeResponse(uint8_t *szBuffer, uint32_t num) {
|
||||
// All character sequences end with \x03 (this is the equiv of a <cr>)
|
||||
//
|
||||
//
|
||||
void ProcessSerialReceive() {
|
||||
bool ProcessSerialReceive() {
|
||||
bool anythingReceived = false;
|
||||
uint8_t rcv_buff[MAXTEXTLEN] = { 0 };
|
||||
static uint8_t messageBuf[MAXTEXTLEN] = { 0 };
|
||||
static uint8_t *p = messageBuf; // used to fill the rcv_buff as data comes in
|
||||
@@ -921,20 +1097,14 @@ void ProcessSerialReceive() {
|
||||
|
||||
p = messageBuf; // Reset the buffer for the next message, which might be in rcv_buff
|
||||
*p = '\0';
|
||||
anythingReceived = true;
|
||||
}
|
||||
}
|
||||
if (messageBuf[0]) {
|
||||
//EmitBuffer("~", messageBuf, true); // Show them the partial receipt if anything is there
|
||||
}
|
||||
} else {
|
||||
// If we're waiting for a response to something we sent, and it's been more than 200ms, resend it
|
||||
if (LastSentMessageTries > 0) {
|
||||
if ((GetTickCount64() - LastSentMessageTime) > 200) {
|
||||
LastSentMessageLen && (GetTickCount64() - LastSentMessageTime) > 200);
|
||||
SerialSend(LastSentMessage, LastSentMessageLen);
|
||||
}
|
||||
//EmitBuffer("~", messageBuf, 0, true); // Show them the partial receipt if anything is there
|
||||
}
|
||||
}
|
||||
return anythingReceived;
|
||||
}
|
||||
|
||||
|
||||
@@ -997,8 +1167,47 @@ int AttachToSerialPort() {
|
||||
void Console_Init() {
|
||||
hStdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
|
||||
wOldColorAttrs = csbiInfo.wAttributes;
|
||||
if (!GetConsoleScreenBufferInfo(hStdout, &csbi)) {
|
||||
fprintf(stderr, "Error: Unable to get console buffer info. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Desired size (width x height)
|
||||
COORD newSize;
|
||||
newSize.X = consoleWidth; // columns
|
||||
newSize.Y = consoleHeight; // rows
|
||||
|
||||
// Step 1: Shrink window if needed before shrinking buffer
|
||||
SMALL_RECT tempWindow = csbi.srWindow;
|
||||
tempWindow.Right = tempWindow.Left + (newSize.X - 1);
|
||||
tempWindow.Bottom = tempWindow.Top + (newSize.Y - 1);
|
||||
|
||||
if (!SetConsoleWindowInfo(hStdout, TRUE, &tempWindow)) {
|
||||
fprintf(stderr, "Error: Unable to temporarily resize window. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Step 2: Set new buffer size
|
||||
if (!SetConsoleScreenBufferSize(hStdout, newSize)) {
|
||||
fprintf(stderr, "Error: Unable to set console buffer size. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Step 3: Set final window size to match buffer
|
||||
SMALL_RECT newWindow;
|
||||
newWindow.Left = 0;
|
||||
newWindow.Top = 0;
|
||||
newWindow.Right = newSize.X - 1;
|
||||
newWindow.Bottom = newSize.Y - 1;
|
||||
|
||||
if (!SetConsoleWindowInfo(hStdout, TRUE, &newWindow)) {
|
||||
fprintf(stderr, "Error: Unable to set console window size. Code: %lu\n", GetLastError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// end
|
||||
|
||||
wOldColorAttrs = csbi.wAttributes;
|
||||
//SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
}
|
||||
|
||||
@@ -1009,7 +1218,6 @@ void Console_Close() {
|
||||
void Console_Cls() {
|
||||
COORD coordScreen = { 0, 0 }; // home for the cursor
|
||||
DWORD cCharsWritten;
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
DWORD dwConSize;
|
||||
|
||||
// Get the number of character cells in the current buffer.
|
||||
@@ -1041,8 +1249,12 @@ void Console_Cls() {
|
||||
SetConsoleCursorPosition(hStdout, coordScreen);
|
||||
}
|
||||
|
||||
void Console_Write(char *text) {
|
||||
void Console_Write(const char *text) {
|
||||
DWORD written;
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbi);
|
||||
if (csbi.dwCursorPosition.Y >= (csbi.srWindow.Bottom - consoleScrollHeight)) {
|
||||
//Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
}
|
||||
WriteConsole(hStdout, text, (DWORD)strlen(text), &written, nullptr);
|
||||
}
|
||||
|
||||
@@ -1053,33 +1265,34 @@ void Console_WriteAt(short x, short y, char *text) {
|
||||
}
|
||||
|
||||
void Console_SetCursor(short x, short y) {
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
|
||||
csbiInfo.dwCursorPosition.X = (short)((x < 0) ? csbiInfo.srWindow.Right + x : x);
|
||||
csbiInfo.dwCursorPosition.Y = (short)((y < 0) ? csbiInfo.srWindow.Bottom + y : y);
|
||||
SetConsoleCursorPosition(hStdout, csbiInfo.dwCursorPosition);
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbi);
|
||||
csbi.dwCursorPosition.X = (short)((x < 0) ? csbi.srWindow.Right + x : x);
|
||||
csbi.dwCursorPosition.Y = (short)((y < 0) ? csbi.srWindow.Bottom + y : y);
|
||||
SetConsoleCursorPosition(hStdout, csbi.dwCursorPosition);
|
||||
}
|
||||
|
||||
void Console_ScrollBottomRegion(short topLine, short bottomLine) {
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
|
||||
if (topLine < 0) topLine = csbiInfo.srWindow.Bottom + topLine;
|
||||
if (bottomLine < 0) bottomLine = csbiInfo.srWindow.Bottom + bottomLine;
|
||||
SMALL_RECT scrollRect = { 0, topLine, csbiInfo.dwMaximumWindowSize.X, bottomLine };
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbi);
|
||||
if (topLine < 0) topLine = csbi.srWindow.Bottom + topLine;
|
||||
if (bottomLine < 0) bottomLine = csbi.srWindow.Bottom + bottomLine;
|
||||
SMALL_RECT scrollRect = { 0, topLine, csbi.dwMaximumWindowSize.X-1, bottomLine };
|
||||
COORD dest = { 0, topLine - 1 };
|
||||
CHAR_INFO fill = { ' ', { FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE } };
|
||||
ScrollConsoleScreenBuffer(hStdout, &scrollRect, nullptr, dest, &fill);
|
||||
ScrollConsoleScreenBuffer(hStdout, &scrollRect, &scrollRect, dest, &fill);
|
||||
putch('\r'); // Cursor to left margin
|
||||
}
|
||||
|
||||
bool Console_AdvanceToNextLineIfNotRoomFor(short x, int scroll) {
|
||||
bool advanced = false;
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
|
||||
if (csbiInfo.dwCursorPosition.X + x > csbiInfo.dwMaximumWindowSize.X) {
|
||||
GetConsoleScreenBufferInfo(hStdout, &csbi);
|
||||
if (csbi.dwCursorPosition.X + x > csbi.dwMaximumWindowSize.X) {
|
||||
advanced = true;
|
||||
if (scroll == 1) {
|
||||
Console_ScrollBottomRegion(-14, -1);
|
||||
Console_ScrollBottomRegion(scrollTop, scrollBot);
|
||||
} else {
|
||||
csbiInfo.dwCursorPosition.Y++;
|
||||
csbi.dwCursorPosition.Y++;
|
||||
}
|
||||
Console_SetCursor(0, csbiInfo.dwCursorPosition.Y);
|
||||
Console_SetCursor(0, csbi.dwCursorPosition.Y);
|
||||
}
|
||||
return advanced;
|
||||
}
|
||||
Reference in New Issue
Block a user