|
@@ -1,15 +1,370 @@
|
|
|
#include "render.h"
|
|
|
#include "terminal.h"
|
|
|
+#include "utils.h"
|
|
|
#include "zf_log.h"
|
|
|
#include <ctype.h>
|
|
|
+#include <sstream>
|
|
|
#include <stdio.h>
|
|
|
#include <string.h>
|
|
|
#include <time.h>
|
|
|
#include <unistd.h> // usleep
|
|
|
#include <vector>
|
|
|
|
|
|
+// Does this copy the terminal?
|
|
|
+
|
|
|
+Render::Render(int fd, Terminal &term) : term(term) {
|
|
|
+ this->fd = fd;
|
|
|
+ reset();
|
|
|
+}
|
|
|
+
|
|
|
+void Render::reset(void) {
|
|
|
+ speed = 0;
|
|
|
+ effect = 0;
|
|
|
+ overlimit = 0;
|
|
|
+ image_data = nullptr; // FUTURE: vector
|
|
|
+ image_size = 0; // FUTURE: vector
|
|
|
+}
|
|
|
+
|
|
|
+void Render::set_image(const char **lines, int size) {
|
|
|
+ image_data = lines;
|
|
|
+ image_size = size;
|
|
|
+}
|
|
|
+
|
|
|
+void Render::reset_image(void) {
|
|
|
+ image_data = nullptr;
|
|
|
+ image_size = 0;
|
|
|
+}
|
|
|
+
|
|
|
+void Render::sleep(void) {
|
|
|
+ if (overlimit)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (speed) { // * 100 still too slow.
|
|
|
+ ms_sleep(speed * 10);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int Render::ms_sleep(unsigned int ms) {
|
|
|
+ int result = 0;
|
|
|
+ struct timespec ts = {ms / 1000, (ms % 1000) * 1000000L};
|
|
|
+
|
|
|
+ do {
|
|
|
+ struct timespec ts_sleep = ts;
|
|
|
+ result = nanosleep(&ts_sleep, &ts);
|
|
|
+ } while ((-1 == result));
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+void Render::color(int color) {
|
|
|
+ const int MYSTIC[] = {0, 4, 2, 6, 1, 5, 3, 7};
|
|
|
+ std::ostringstream oss;
|
|
|
+
|
|
|
+ switch (color) {
|
|
|
+ case 0:
|
|
|
+ case 1:
|
|
|
+ case 2:
|
|
|
+ case 3:
|
|
|
+ case 4:
|
|
|
+ case 5:
|
|
|
+ case 6:
|
|
|
+ case 7:
|
|
|
+ oss << "\x1b[0;" << MYSTIC[color] + 30 << "m";
|
|
|
+ break;
|
|
|
+ case 8:
|
|
|
+ case 9:
|
|
|
+ case 10:
|
|
|
+ case 11:
|
|
|
+ case 12:
|
|
|
+ case 13:
|
|
|
+ case 14:
|
|
|
+ case 15:
|
|
|
+ oss << "\x1b[0;1;" << MYSTIC[color] + 30 << "m";
|
|
|
+ break;
|
|
|
+ case 16:
|
|
|
+ case 17:
|
|
|
+ case 18:
|
|
|
+ case 19:
|
|
|
+ case 20:
|
|
|
+ case 21:
|
|
|
+ case 22:
|
|
|
+ case 23:
|
|
|
+ oss << "\x1b[" << MYSTIC[color] + 40 << "m";
|
|
|
+ break;
|
|
|
+ case 24:
|
|
|
+ case 25:
|
|
|
+ case 26:
|
|
|
+ case 27:
|
|
|
+ case 28:
|
|
|
+ case 29:
|
|
|
+ case 30:
|
|
|
+ case 31:
|
|
|
+ oss << "\x1b[5;" << MYSTIC[color] + 40 << "m";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ std::string buffer = oss.str();
|
|
|
+ ZF_LOGD("write_color( %d ): %s", color, repr(buffer.c_str()));
|
|
|
+ write(fd, buffer.c_str(), buffer.size());
|
|
|
+}
|
|
|
+
|
|
|
+void Render::pos_goto(int x, int y) {
|
|
|
+ std::ostringstream oss;
|
|
|
+
|
|
|
+ oss << "\x1b[" << y << ";" << x << "H";
|
|
|
+ std::string buffer = oss.str();
|
|
|
+ write(fd, buffer.c_str(), buffer.size());
|
|
|
+};
|
|
|
+
|
|
|
+void Render::send(char ch) { // render_effect
|
|
|
+ // int effect = effect;
|
|
|
+ int l;
|
|
|
+ char space = ' ';
|
|
|
+ char bs = '\b';
|
|
|
+ Terminal::termchar tc;
|
|
|
+
|
|
|
+ tc = term.putchar(ch);
|
|
|
+ if (tc.in_ansi) {
|
|
|
+ // We are inside ANSI command, so
|
|
|
+ write(fd, &ch, 1);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (effect) {
|
|
|
+ case 1:
|
|
|
+ // CHAR + SPC + BS
|
|
|
+ render_sleep();
|
|
|
+ write(fd, &ch, 1);
|
|
|
+ render_sleep();
|
|
|
+ write(fd, &space, 1);
|
|
|
+ render_sleep();
|
|
|
+ render_sleep();
|
|
|
+ write(fd, &bs, 1);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ // CHAR + 8 spaces + 8 BS
|
|
|
+ // This might be too much.
|
|
|
+#define MOVE 4
|
|
|
+ render_sleep();
|
|
|
+ write(fd, &ch, 1);
|
|
|
+ for (l = 0; l < MOVE; l++) {
|
|
|
+ render_sleep();
|
|
|
+ write(fd, &space, 1);
|
|
|
+ }
|
|
|
+ for (l = 0; l < MOVE; l++) {
|
|
|
+ render_sleep();
|
|
|
+ write(fd, &bs, 1);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 0:
|
|
|
+ default:
|
|
|
+ // NORMAL
|
|
|
+ render_sleep();
|
|
|
+ write(fd, &ch, 1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Render::send(std::string &string_out) { // render
|
|
|
+ time_t start = time(NULL);
|
|
|
+ size_t pos = 0;
|
|
|
+ int elapsed;
|
|
|
+ size_t tpos;
|
|
|
+
|
|
|
+ while ((tpos = string_out.find(TRIGGER, pos)) != std::string::npos) {
|
|
|
+ while (pos != tpos) {
|
|
|
+ elapsed = time(NULL) - start;
|
|
|
+ if (elapsed > SLEEP_LIMIT) {
|
|
|
+ overlimit = 1;
|
|
|
+ speed = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ send(string_out[pos]);
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+
|
|
|
+ pos += strlen(TRIGGER);
|
|
|
+ process_trigger(string_out, pos);
|
|
|
+ }
|
|
|
+
|
|
|
+ while (pos < string_out.size()) {
|
|
|
+ elapsed = time(NULL) - start;
|
|
|
+ if (elapsed > SLEEP_LIMIT) {
|
|
|
+ overlimit = 1;
|
|
|
+ speed = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ send(string_out[pos]);
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int Render::digit(std::string str, size_t &pos, int digits) {
|
|
|
+ int i = 0;
|
|
|
+
|
|
|
+ while (digits > 0) {
|
|
|
+ if (std::isdigit(str[pos])) {
|
|
|
+ i *= 10;
|
|
|
+ i += str[pos] - '0';
|
|
|
+ pos++;
|
|
|
+ } else {
|
|
|
+ ZF_LOGE("digit fail");
|
|
|
+ }
|
|
|
+ digits--;
|
|
|
+ };
|
|
|
+ return i;
|
|
|
+}
|
|
|
+
|
|
|
+void Render::process_trigger(std::string str, size_t &pos) {
|
|
|
+ char ch = str[pos];
|
|
|
+ int i, x, y;
|
|
|
+ pos++;
|
|
|
+ switch (ch) {
|
|
|
+ case 'D':
|
|
|
+ i = digit(str, pos, 2);
|
|
|
+
|
|
|
+ if ((i > 0) && (i < 80)) {
|
|
|
+ ZF_LOGI("DEL %02d", i);
|
|
|
+
|
|
|
+ for (x = 0; x < i; x++) {
|
|
|
+ write(fd, "\b \b", 3);
|
|
|
+ term.putstring("\b \b");
|
|
|
+ }
|
|
|
+ };
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'C': {
|
|
|
+ i = 0;
|
|
|
+ if (str[pos] == 'S') {
|
|
|
+ pos++;
|
|
|
+ color_history.push_back(term.color_restore());
|
|
|
+ // console_history.push_back(console);
|
|
|
+ ZF_LOGI("saved color.");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (str[pos] == 'R') {
|
|
|
+ pos++;
|
|
|
+ if (color_history.empty()) {
|
|
|
+ ZF_LOGE("Trying to Color Restore from empty vector!");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ std::string restore = color_history.back();
|
|
|
+ color_history.pop_back();
|
|
|
+ write(fd, restore.c_str(), restore.size());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ i = digit(str, pos, 2);
|
|
|
+ write_color(fd, i);
|
|
|
+ } break;
|
|
|
+
|
|
|
+ // no longer takes a filename. :)
|
|
|
+ case 'F':
|
|
|
+ case 'f': {
|
|
|
+ int UsePos = 0;
|
|
|
+ if (ch == 'f') {
|
|
|
+ UsePos = 1;
|
|
|
+ x = digit(str, pos, 2);
|
|
|
+ y = digit(str, pos, 2);
|
|
|
+ ZF_LOGI("file at (%d, %d)", x, y);
|
|
|
+ }
|
|
|
+ ZF_LOGD("IMAGE (%d lines)", image_size);
|
|
|
+ if (UsePos) {
|
|
|
+ send_image(x, y);
|
|
|
+ } else {
|
|
|
+ send_image();
|
|
|
+ };
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case 'G': {
|
|
|
+ x = digit(str, pos, 2);
|
|
|
+ y = digit(str, pos, 2);
|
|
|
+ char buffer[20]; // row ; column H
|
|
|
+ int slen;
|
|
|
+ ZF_LOGD("GOTO (%d,%d)", x, y);
|
|
|
+ slen = snprintf(buffer, sizeof(buffer), "\x1b[%d;%dH", y, x);
|
|
|
+ if (slen >= (int)sizeof(buffer)) {
|
|
|
+ ZF_LOGE("snprintf %d > size %d", slen, (int)sizeof(buffer));
|
|
|
+ buffer[0] = 0;
|
|
|
+ }
|
|
|
+ write(fd, buffer, strlen(buffer));
|
|
|
+ } break;
|
|
|
+
|
|
|
+ case 'R': {
|
|
|
+ i = digit(str, pos);
|
|
|
+ if ((i > 0) && (i < 10)) {
|
|
|
+ ZF_LOGI("RENDER %d", i);
|
|
|
+ effect = i;
|
|
|
+ } else {
|
|
|
+ effect = 0;
|
|
|
+ }
|
|
|
+ } break;
|
|
|
+ case 'S': {
|
|
|
+ i = digit(str, pos);
|
|
|
+ if ((i > 0) && (i < 10)) {
|
|
|
+ ZF_LOGI("SPEED %d", i);
|
|
|
+ speed = i;
|
|
|
+ } else {
|
|
|
+ speed = 0;
|
|
|
+ }
|
|
|
+ } break;
|
|
|
+ case 'P': {
|
|
|
+ i = digit(str, pos);
|
|
|
+ if ((i > 0) && (i < 10)) {
|
|
|
+ ZF_LOGI("PAWS %d", i);
|
|
|
+ // sleep(i);
|
|
|
+ if (!overlimit) {
|
|
|
+ // sleep(i);
|
|
|
+ ms_sleep(i * 1000);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ } break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int Render::send_image(int x, int y) {
|
|
|
+ int i;
|
|
|
+ const char **lines = image_data;
|
|
|
+
|
|
|
+ if (lines == nullptr) {
|
|
|
+ ZF_LOGE("No image data for send_image(%d,%d)", x, y);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < image_size; i++) {
|
|
|
+ send_goto(fd, x, y);
|
|
|
+ y++;
|
|
|
+ write(fd, lines[i], strlen(lines[i]));
|
|
|
+ }
|
|
|
+
|
|
|
+ // success
|
|
|
+ reset_image();
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int Render::send_image(void) {
|
|
|
+ int i;
|
|
|
+ const char **lines = image_data;
|
|
|
+
|
|
|
+ if (lines == nullptr) {
|
|
|
+ ZF_LOGE("No image data for send_image.");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < image_size; i++) {
|
|
|
+ std::string line(lines[i]);
|
|
|
+ line.append("\r\n");
|
|
|
+ // rendering the ^BAT^ was a bad idea. (uses ^ chars).
|
|
|
+ // render(fd, line);
|
|
|
+ write(fd, lines[i], strlen(lines[i]));
|
|
|
+ write(fd, "\r\n", 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // success
|
|
|
+ reset_image();
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
extern const char *strnstr(const char *source, int len, const char *needle);
|
|
|
-extern const char *repr(const char *data);
|
|
|
extern struct console_details console;
|
|
|
|
|
|
struct render current_render;
|
|
@@ -245,58 +600,6 @@ int send_image(int fd, int x, int y) {
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-#ifdef UNWANTED
|
|
|
-int send_file(int fd, char *filename) {
|
|
|
- FILE *fp;
|
|
|
- char buffer[100];
|
|
|
- int read;
|
|
|
-
|
|
|
- fp = fopen(filename, "rb");
|
|
|
- if (fp == NULL) {
|
|
|
- ZF_LOGD("Failed to open %s", filename);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- while ((read = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
|
|
|
- write(fd, buffer, read);
|
|
|
- };
|
|
|
- fclose(fp);
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-int send_file(int fd, int x, int y, char *filename) {
|
|
|
- FILE *fp;
|
|
|
- char buffer[100];
|
|
|
- int read;
|
|
|
-
|
|
|
- fp = fopen(filename, "rb");
|
|
|
- if (fp == NULL) {
|
|
|
- ZF_LOGD("Failed to open %s", filename);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- send_goto(fd, x, y);
|
|
|
- y++;
|
|
|
-
|
|
|
- while ((read = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
|
|
|
- char *cp, *last_cp;
|
|
|
-
|
|
|
- buffer[read] = 0;
|
|
|
- last_cp = buffer;
|
|
|
- while ((cp = strchr(last_cp, '\n')) != NULL) {
|
|
|
- *cp = 0;
|
|
|
- write(fd, last_cp, strlen(last_cp));
|
|
|
- send_goto(fd, x, y);
|
|
|
- y++;
|
|
|
- last_cp = cp + 1;
|
|
|
- };
|
|
|
- write(fd, last_cp, strlen(last_cp));
|
|
|
- };
|
|
|
- fclose(fp);
|
|
|
- return 1;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
int digit(std::string str, size_t &pos, int digits = 1) {
|
|
|
int i = 0;
|
|
|
|
|
@@ -429,170 +732,6 @@ void process_trigger(int fd, std::string str, size_t &pos) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#ifdef UNWANTED
|
|
|
-/**
|
|
|
- * process_trigger( fd, *cp )
|
|
|
- *
|
|
|
- * This process a command trigger.
|
|
|
- * It has seen TRIGGER, and now it is
|
|
|
- * processing whatever comes after it.
|
|
|
- * It will perform the process, and
|
|
|
- * return the char * of whatever is next.
|
|
|
- */
|
|
|
-const char *process_trigger(int fd, const char *cp) {
|
|
|
- char ch;
|
|
|
- int i, x, y;
|
|
|
- ch = *cp;
|
|
|
- cp++;
|
|
|
-
|
|
|
- switch (ch) {
|
|
|
- case 'D':
|
|
|
- i = 0;
|
|
|
- if (isdigit(*cp)) {
|
|
|
- i = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- if (isdigit(*cp)) {
|
|
|
- i *= 10;
|
|
|
- i += (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
-
|
|
|
- if ((i > 0) && (i < 80)) {
|
|
|
- ZF_LOGI("DEL %02d", i);
|
|
|
-
|
|
|
- for (x = 0; x < i; x++) {
|
|
|
- write(fd, "\b \b", 3);
|
|
|
- console_receive(&console, "\b \b");
|
|
|
- }
|
|
|
- };
|
|
|
- break;
|
|
|
-
|
|
|
- case 'C': {
|
|
|
- i = 0;
|
|
|
- if (*cp == 'R') {
|
|
|
- cp++;
|
|
|
- const char *restore = color_restore(&console);
|
|
|
- write(fd, restore, strlen(restore));
|
|
|
- break;
|
|
|
- }
|
|
|
- if (isdigit(*cp)) {
|
|
|
- i = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- if (isdigit(*cp)) {
|
|
|
- i *= 10;
|
|
|
- i += (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- write_color(fd, i);
|
|
|
- } break;
|
|
|
-
|
|
|
- // no longer takes a filename. :)
|
|
|
- case 'F':
|
|
|
- case 'f': {
|
|
|
- int pos = 0;
|
|
|
- if (ch == 'f') {
|
|
|
- pos = 1;
|
|
|
- x = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- x *= 10;
|
|
|
- x += (*cp) - '0';
|
|
|
- cp++;
|
|
|
- y = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- y *= 10;
|
|
|
- y += (*cp) - '0';
|
|
|
- cp++;
|
|
|
- ZF_LOGI("file at (%d, %d)", x, y);
|
|
|
- }
|
|
|
- ZF_LOGD("IMAGE (%d lines)", image_size);
|
|
|
- if (pos) {
|
|
|
- send_image(fd, x, y);
|
|
|
- } else {
|
|
|
- send_image(fd);
|
|
|
- };
|
|
|
- } break;
|
|
|
-
|
|
|
- case 'G': {
|
|
|
- x = 0;
|
|
|
- if (isdigit(*cp)) {
|
|
|
- x = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- if (isdigit(*cp)) {
|
|
|
- x *= 10;
|
|
|
- x += (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- y = 0;
|
|
|
- if (isdigit(*cp)) {
|
|
|
- y = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- if (isdigit(*cp)) {
|
|
|
- y *= 10;
|
|
|
- y += (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- char buffer[20]; // row ; column H
|
|
|
- int slen;
|
|
|
- ZF_LOGD("GOTO (%d,%d)", x, y);
|
|
|
- slen = snprintf(buffer, sizeof(buffer), "\x1b[%d;%dH", y, x);
|
|
|
- if (slen >= (int)sizeof(buffer)) {
|
|
|
- ZF_LOGE("snprintf %d > size %d", slen, (int)sizeof(buffer));
|
|
|
- buffer[0] = 0;
|
|
|
- }
|
|
|
- write(fd, buffer, strlen(buffer));
|
|
|
- } break;
|
|
|
-
|
|
|
- case 'R': {
|
|
|
- i = 0;
|
|
|
- if (isdigit(*cp)) {
|
|
|
- i = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- if ((i > 0) && (i < 10)) {
|
|
|
- ZF_LOGI("RENDER %d", i);
|
|
|
- current_render.effect = i;
|
|
|
- } else {
|
|
|
- ZF_LOGI("RENDER OFF");
|
|
|
- current_render.effect = 0;
|
|
|
- }
|
|
|
- } break;
|
|
|
- case 'S': {
|
|
|
- i = 0;
|
|
|
- if (isdigit(*cp)) {
|
|
|
- i = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- if ((i > 0) && (i < 10)) {
|
|
|
- ZF_LOGI("SPEED %d", i);
|
|
|
- current_render.speed = i;
|
|
|
- } else {
|
|
|
- ZF_LOGI("SPEED OFF");
|
|
|
- current_render.speed = 0;
|
|
|
- }
|
|
|
- } break;
|
|
|
- case 'P': {
|
|
|
- i = 0;
|
|
|
- if (isdigit(*cp)) {
|
|
|
- i = (*cp) - '0';
|
|
|
- cp++;
|
|
|
- };
|
|
|
- if ((i > 0) && (i < 10)) {
|
|
|
- ZF_LOGI("PAWS %d", i);
|
|
|
- // sleep(i);
|
|
|
- if (!render_overlimit) {
|
|
|
- sleep(i);
|
|
|
- };
|
|
|
- }
|
|
|
- } break;
|
|
|
- }
|
|
|
- return cp;
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
/**
|
|
|
* render_effect( fd, ch )
|
|
|
*
|
|
@@ -649,67 +788,6 @@ void render_effect(int fd, char ch) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#ifdef UNWANTED
|
|
|
-/**
|
|
|
- * render( fd, string_out )
|
|
|
- *
|
|
|
- * Render an entire string.
|
|
|
- * Handles TRIGGER.
|
|
|
- * Renders with effects.
|
|
|
- */
|
|
|
-void render(int fd, const char *string_out, int len) {
|
|
|
- const char *cp = string_out;
|
|
|
- const char *trigger = cp;
|
|
|
-
|
|
|
- time_t start = time(NULL);
|
|
|
- int elapsed;
|
|
|
- int over = 0;
|
|
|
-
|
|
|
- reset_render();
|
|
|
-
|
|
|
- // ZF_LOGV("render(%d, %s)", fd, repr(string_out));
|
|
|
- ZF_LOGV_MEM(string_out, len, "render(%d, %d bytes):", fd, len);
|
|
|
-
|
|
|
- // Check our time from time to time.
|
|
|
- // If we start running long, disable sleeps.
|
|
|
-
|
|
|
- while ((trigger = strnstr(cp, len - (cp - string_out), TRIGGER)) != NULL) {
|
|
|
- // There is special things to handle in here.
|
|
|
- while (cp != trigger) {
|
|
|
- elapsed = time(NULL) - start;
|
|
|
- if (elapsed > SLEEP_LIMIT) {
|
|
|
- render_overlimit = 1;
|
|
|
- current_render.speed = 0;
|
|
|
- };
|
|
|
-
|
|
|
- // write(fd, cp, 1 );
|
|
|
- render_effect(fd, *cp);
|
|
|
- cp++;
|
|
|
- };
|
|
|
-
|
|
|
- // ZF_LOGI( "at trigger: (%s)", cp);
|
|
|
- cp += strlen(TRIGGER);
|
|
|
-
|
|
|
- // Ok, we're pointing at the trigger -- do something.
|
|
|
- cp = process_trigger(fd, cp);
|
|
|
-
|
|
|
- // ZF_LOGI( "after trigger: (%s)", cp);
|
|
|
- };
|
|
|
-
|
|
|
- // We still might be under a rendering effect.
|
|
|
- while (cp < (string_out + len)) {
|
|
|
- elapsed = time(NULL) - start;
|
|
|
- if (elapsed > SLEEP_LIMIT) {
|
|
|
- render_overlimit = 1;
|
|
|
- current_render.speed = 0;
|
|
|
- };
|
|
|
- // write(fd, cp, 1);
|
|
|
- render_effect(fd, *cp);
|
|
|
- cp++;
|
|
|
- }
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
/**
|
|
|
* render( fd, string_out )
|
|
|
*
|