浏览代码

Console working.

Added quit command. Fixed bug in bufferString segfaulting with too big strings.
Thomas Buck 11 年前
父节点
当前提交
5a7d335545
共有 5 个文件被更改,包括 158 次插入28 次删除
  1. 9
    0
      include/Console.h
  2. 116
    2
      src/Console.cpp
  3. 21
    19
      src/OpenRaider.cpp
  4. 2
    2
      src/main.cpp
  5. 10
    5
      src/utils/strings.cpp

+ 9
- 0
include/Console.h 查看文件

8
 #ifndef _CONSOLE_H_
8
 #ifndef _CONSOLE_H_
9
 #define _CONSOLE_H_
9
 #define _CONSOLE_H_
10
 
10
 
11
+#include <cstring>
12
+#include <vector>
13
+
11
 #include "Window.h"
14
 #include "Window.h"
12
 
15
 
13
 /*!
16
 /*!
30
 
33
 
31
     bool isVisible();
34
     bool isVisible();
32
 
35
 
36
+    void print(const char *s, ...) __attribute__((format(printf, 2, 3)));
37
+
33
     void display();
38
     void display();
34
 
39
 
35
     void handleKeyboard(KeyboardButton key, bool pressed);
40
     void handleKeyboard(KeyboardButton key, bool pressed);
39
 private:
44
 private:
40
 
45
 
41
     bool mVisible;
46
     bool mVisible;
47
+    char *mInputBuffer;
48
+    size_t mInputBufferPointer;
49
+    char *mPartialInput;
50
+    std::vector<char *> mHistory;
42
 };
51
 };
43
 
52
 
44
 #endif
53
 #endif

+ 116
- 2
src/Console.cpp 查看文件

16
 #include "config.h"
16
 #include "config.h"
17
 #include "Console.h"
17
 #include "Console.h"
18
 #include "main.h"
18
 #include "main.h"
19
+#include "utils/strings.h"
19
 #include "utils/time.h"
20
 #include "utils/time.h"
20
 
21
 
22
+#define INPUT_BUFFER_SIZE 255
23
+
21
 Console::Console() {
24
 Console::Console() {
22
     mVisible = false;
25
     mVisible = false;
26
+    mInputBuffer = new char[INPUT_BUFFER_SIZE + 1];
27
+    mInputBuffer[INPUT_BUFFER_SIZE] = '\0';
28
+    mInputBufferPointer = 0;
29
+    mPartialInput = NULL;
23
 }
30
 }
24
 
31
 
25
 Console::~Console() {
32
 Console::~Console() {
33
+    if (mInputBuffer)
34
+        delete [] mInputBuffer;
35
+
36
+    if (mPartialInput)
37
+        delete [] mPartialInput;
38
+
39
+    while (mHistory.size() > 0) {
40
+        char *tmp = mHistory.back();
41
+        if (tmp != NULL)
42
+            delete [] tmp;
43
+        mHistory.pop_back();
44
+    }
26
 }
45
 }
27
 
46
 
28
 void Console::setVisible(bool visible) {
47
 void Console::setVisible(bool visible) {
34
     return mVisible;
53
     return mVisible;
35
 }
54
 }
36
 
55
 
56
+void Console::print(const char *s, ...) {
57
+    va_list args;
58
+    va_start(args, s);
59
+    char *tmp = bufferString(s, args);
60
+    va_end(args);
61
+
62
+    if (tmp != NULL) {
63
+        mHistory.push_back(tmp);
64
+        printf("%s\n", tmp);
65
+    }
66
+}
67
+
37
 void Console::display() {
68
 void Console::display() {
38
     Window *window = gOpenRaider->mWindow;
69
     Window *window = gOpenRaider->mWindow;
39
     unsigned char color[4] = {0xFF, 0xFF, 0xFF, 0xFF};
70
     unsigned char color[4] = {0xFF, 0xFF, 0xFF, 0xFF};
40
 
71
 
41
     if (mVisible) {
72
     if (mVisible) {
73
+        // Calculate line drawing geometry
74
+        // Depends on window height, so recalculate every time
75
+        unsigned int firstLine = 35;
76
+        unsigned int lastLine = (window->mHeight / 2) - 55;
77
+        unsigned int inputLine = (window->mHeight / 2) - 30;
78
+        unsigned int lineSteps = 20;
79
+        unsigned int lineCount = (lastLine - firstLine + lineSteps) / lineSteps;
80
+        while (((lineCount * lineSteps) + firstLine) < inputLine) {
81
+            lineSteps++;
82
+            lineCount = (lastLine - firstLine + lineSteps) / lineSteps;
83
+        }
84
+
42
         // Draw half-transparent *overlay*
85
         // Draw half-transparent *overlay*
43
         glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
86
         glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
44
         glDisable(GL_TEXTURE_2D);
87
         glDisable(GL_TEXTURE_2D);
45
         glRecti(0, 0, window->mWidth, window->mHeight / 2);
88
         glRecti(0, 0, window->mWidth, window->mHeight / 2);
46
         glEnable(GL_TEXTURE_2D);
89
         glEnable(GL_TEXTURE_2D);
47
 
90
 
48
-        gOpenRaider->mWindow->drawText(10, 10, 0.50f, color, "%lus uptime %s", systemTimerGet() / 1000, VERSION);
91
+        gOpenRaider->mWindow->drawText(10, 10, 0.70f, color, "%s uptime %lus", VERSION, systemTimerGet() / 1000);
92
+
93
+        // Draw output log
94
+        int end = lineCount;
95
+        int drawOffset = 0;
96
+        int historyOffset = 0;
97
+        if (mHistory.size() < lineCount) {
98
+            end = mHistory.size();
99
+            drawOffset = lineCount - mHistory.size();
100
+        } else if (lineCount < mHistory.size()) {
101
+            historyOffset = mHistory.size() - lineCount;
102
+        }
103
+        for (int i = 0; i < end; i++) {
104
+            gOpenRaider->mWindow->drawText(10, ((i + drawOffset) * lineSteps) + firstLine,
105
+                    0.75f, color, "%s", mHistory[i + historyOffset]);
106
+        }
107
+
108
+        // Draw current input
109
+        if ((mInputBufferPointer > 0) && (mInputBuffer[0] != '\0')) {
110
+            gOpenRaider->mWindow->drawText(10, inputLine, 0.75f, color, "> %s", mInputBuffer);
111
+        } else {
112
+            gOpenRaider->mWindow->drawText(10, inputLine, 0.75f, color, ">");
113
+        }
114
+
115
+        //! \todo display the current mPartialInput. The UTF-8 segfaults SDL-TTF, somehow?
49
     }
116
     }
50
 }
117
 }
51
 
118
 
52
 void Console::handleKeyboard(KeyboardButton key, bool pressed) {
119
 void Console::handleKeyboard(KeyboardButton key, bool pressed) {
53
     if (pressed && (key == enter)) {
120
     if (pressed && (key == enter)) {
121
+        // Execute entered command
122
+        if ((mInputBufferPointer > 0) && (mInputBuffer[0] != '\0')) {
123
+            mHistory.push_back(bufferString("> %s", mInputBuffer));
124
+            gOpenRaider->command(mInputBuffer);
125
+        }
126
+
127
+        // Clear partial and input buffer
128
+        mInputBufferPointer = 0;
129
+        mInputBuffer[0] = '\0';
130
+        if (mPartialInput != NULL) {
131
+            delete [] mPartialInput;
132
+            mPartialInput = NULL;
133
+        }
134
+    }
54
 
135
 
136
+    //! \fixme only deleting the last byte is not valid for non-ASCII UTF-8 strings
137
+    if (pressed && (key == backspace)) {
138
+        if (mInputBufferPointer > 0) {
139
+            mInputBufferPointer--;
140
+            mInputBuffer[mInputBufferPointer] = '\0';
141
+        }
55
     }
142
     }
56
 }
143
 }
57
 
144
 
58
 void Console::handleText(char *text, bool notFinished) {
145
 void Console::handleText(char *text, bool notFinished) {
59
-    printf("Got %s (%s)\n", text, (notFinished ? "not finished" : "finished"));
146
+    //printf("Text: %s (%s)\n", text, (notFinished ? "not finished" : "finished"));
147
+
148
+    if (!notFinished) {
149
+        // Finished entering character
150
+        // delete previous partial character, if present
151
+        if (mPartialInput != NULL) {
152
+            delete [] mPartialInput;
153
+        }
154
+
155
+        //! \fixme Temporary hack filtering the console activation key
156
+        if (text[0] == '`')
157
+            return;
158
+
159
+        // Append new input to buffer
160
+        size_t length = strlen(text);
161
+        if (length > 0) {
162
+            if (((INPUT_BUFFER_SIZE - mInputBufferPointer) < length)) {
163
+                printf("Console input buffer overflowed! (> %d)\n", INPUT_BUFFER_SIZE);
164
+                return;
165
+            }
166
+            strcpy((mInputBuffer + mInputBufferPointer), text);
167
+            mInputBufferPointer += length;
168
+            mInputBuffer[mInputBufferPointer] = '\0';
169
+        }
170
+    } else {
171
+        // Partial character received
172
+        mPartialInput = bufferString("%s", text);
173
+    }
60
 }
174
 }
61
 
175
 

+ 21
- 19
src/OpenRaider.cpp 查看文件

73
     assert(config[0] != '\0');
73
     assert(config[0] != '\0');
74
 
74
 
75
     char *configFile = fullPath(config, 0);
75
     char *configFile = fullPath(config, 0);
76
-    printf("Loading config from \"%s\"...\n", configFile);
76
+    mConsole->print("Loading config from \"%s\"...", configFile);
77
 
77
 
78
     FILE *f = fopen(configFile, "r");
78
     FILE *f = fopen(configFile, "r");
79
     if (f == NULL) {
79
     if (f == NULL) {
80
-        printf("Could not open file!\n");
80
+        mConsole->print("Could not open file!");
81
         return -1;
81
         return -1;
82
     }
82
     }
83
 
83
 
132
 
132
 
133
     if (strcmp(command, "set") == 0) {
133
     if (strcmp(command, "set") == 0) {
134
         if (args->size() != 2) {
134
         if (args->size() != 2) {
135
-            printf("Invalid use of set-command ");
135
+            mConsole->print("Invalid use of set-command ");
136
             printStringVector(args);
136
             printStringVector(args);
137
             printf("\n");
137
             printf("\n");
138
             return -2;
138
             return -2;
141
         }
141
         }
142
     } else if (strcmp(command, "bind") == 0) {
142
     } else if (strcmp(command, "bind") == 0) {
143
         if (args->size() != 2) {
143
         if (args->size() != 2) {
144
-            printf("Invalid use of bind-command ");
144
+            mConsole->print("Invalid use of bind-command ");
145
             printStringVector(args);
145
             printStringVector(args);
146
             printf("\n");
146
             printf("\n");
147
             return -3;
147
             return -3;
148
         } else {
148
         } else {
149
             return bind(args->at(0), args->at(1));
149
             return bind(args->at(0), args->at(1));
150
         }
150
         }
151
+    } else if (strcmp(command, "quit") == 0) {
152
+        exit(0);
151
     } else {
153
     } else {
152
-        printf("Unknown command: %s ", command);
154
+        mConsole->print("Unknown command: %s ", command);
153
         printStringVector(args);
155
         printStringVector(args);
154
         printf("\n");
156
         printf("\n");
155
         return -1;
157
         return -1;
206
         // value has format like "\"1024x768\""
208
         // value has format like "\"1024x768\""
207
         unsigned int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;
209
         unsigned int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;
208
         if (sscanf(value, "\"%dx%d\"", &w, &h) != 2) {
210
         if (sscanf(value, "\"%dx%d\"", &w, &h) != 2) {
209
-            printf("set-size-Error: Invalid value (%s)\n", value);
211
+            mConsole->print("set-size-Error: Invalid value (%s)", value);
210
             return -2;
212
             return -2;
211
         }
213
         }
212
         mWindow->setSize(w, h);
214
         mWindow->setSize(w, h);
213
     } else if (strcmp(var, "fullscreen") == 0) {
215
     } else if (strcmp(var, "fullscreen") == 0) {
214
         bool fullscreen = false;
216
         bool fullscreen = false;
215
         if (readBool(value, &fullscreen) != 0) {
217
         if (readBool(value, &fullscreen) != 0) {
216
-            printf("set-fullscreen-Error: Invalid value (%s)\n", value);
218
+            mConsole->print("set-fullscreen-Error: Invalid value (%s)", value);
217
             return -3;
219
             return -3;
218
         }
220
         }
219
         mWindow->setFullscreen(fullscreen);
221
         mWindow->setFullscreen(fullscreen);
222
     } else if (strcmp(var, "audio") == 0) {
224
     } else if (strcmp(var, "audio") == 0) {
223
         bool audio = false;
225
         bool audio = false;
224
         if (readBool(value, &audio) != 0) {
226
         if (readBool(value, &audio) != 0) {
225
-            printf("set-audio-Error: Invalid value (%s)\n", value);
227
+            mConsole->print("set-audio-Error: Invalid value (%s)", value);
226
             return -4;
228
             return -4;
227
         }
229
         }
228
         mSound->setEnabled(audio);
230
         mSound->setEnabled(audio);
229
     } else if (strcmp(var, "volume") == 0) {
231
     } else if (strcmp(var, "volume") == 0) {
230
         float vol = 1.0f;
232
         float vol = 1.0f;
231
         if (sscanf(value, "%f", &vol) != 1) {
233
         if (sscanf(value, "%f", &vol) != 1) {
232
-            printf("set-volume-Error: Invalid value (%s)\n", value);
234
+            mConsole->print("set-volume-Error: Invalid value (%s)", value);
233
             return -5;
235
             return -5;
234
         }
236
         }
235
         mSound->setVolume(vol);
237
         mSound->setVolume(vol);
236
     } else if (strcmp(var, "mouse_x") == 0) {
238
     } else if (strcmp(var, "mouse_x") == 0) {
237
         float sense = 1.0f;
239
         float sense = 1.0f;
238
         if (sscanf(value, "%f", &sense) != 1) {
240
         if (sscanf(value, "%f", &sense) != 1) {
239
-            printf("set-mouse_x-Error: Invalid value (%s)\n", value);
241
+            mConsole->print("set-mouse_x-Error: Invalid value (%s)", value);
240
             return -6;
242
             return -6;
241
         }
243
         }
242
         //! \todo mouse support
244
         //! \todo mouse support
243
     } else if (strcmp(var, "mouse_y") == 0) {
245
     } else if (strcmp(var, "mouse_y") == 0) {
244
         float sense = 1.0f;
246
         float sense = 1.0f;
245
         if (sscanf(value, "%f", &sense) != 1) {
247
         if (sscanf(value, "%f", &sense) != 1) {
246
-            printf("set-mouse_y-Error: Invalid value (%s)\n", value);
248
+            mConsole->print("set-mouse_y-Error: Invalid value (%s)", value);
247
             return -7;
249
             return -7;
248
         }
250
         }
249
         //! \todo mouse support
251
         //! \todo mouse support
266
         }
268
         }
267
         delete [] quotes;
269
         delete [] quotes;
268
     } else {
270
     } else {
269
-        printf("set-Error: Unknown variable (%s = %s)\n", var, value);
271
+        mConsole->print("set-Error: Unknown variable (%s = %s)", var, value);
270
         return -1;
272
         return -1;
271
     }
273
     }
272
 
274
 
299
     } else if (strcmp(tmp, "holster") == 0) {
301
     } else if (strcmp(tmp, "holster") == 0) {
300
         return bind(holster, key);
302
         return bind(holster, key);
301
     } else {
303
     } else {
302
-        printf("bind-Error: Unknown action (%s --> %s)\n", key, action);
304
+        mConsole->print("bind-Error: Unknown action (%s --> %s)", key, action);
303
         return -1;
305
         return -1;
304
     }
306
     }
305
 }
307
 }
317
             || ((c >= 'a') && (c <= 'z'))) {
319
             || ((c >= 'a') && (c <= 'z'))) {
318
             keyBindings[action] = (KeyboardButton)c;
320
             keyBindings[action] = (KeyboardButton)c;
319
         } else {
321
         } else {
320
-            printf("bind-\'\'-Error: Unknown key (%s)\n", key);
322
+            mConsole->print("bind-\'\'-Error: Unknown key (%s)", key);
321
             return -1;
323
             return -1;
322
         }
324
         }
323
     } else if ((key[0] == '\"') && (key[length - 1] == '\"')) {
325
     } else if ((key[0] == '\"') && (key[length - 1] == '\"')) {
424
         } else if (strcmp(tmp, "tab") == 0) {
426
         } else if (strcmp(tmp, "tab") == 0) {
425
             keyBindings[action] = tab;
427
             keyBindings[action] = tab;
426
         } else {
428
         } else {
427
-            printf("bind-\"\"-Error: Unknown key (%s)\n", key);
429
+            mConsole->print("bind-\"\"-Error: Unknown key (%s)", key);
428
             delete [] tmp;
430
             delete [] tmp;
429
             return -2;
431
             return -2;
430
         }
432
         }
431
         delete [] tmp;
433
         delete [] tmp;
432
     } else {
434
     } else {
433
-        printf("bind-Error: Unknown key (%s)\n", key);
435
+        mConsole->print("bind-Error: Unknown key (%s)", key);
434
         return -3;
436
         return -3;
435
     }
437
     }
436
     return 0;
438
     return 0;
464
                      || stringEndsWith(lowerPath, ".tr4")
466
                      || stringEndsWith(lowerPath, ".tr4")
465
                      || stringEndsWith(lowerPath, ".trc")) {
467
                      || stringEndsWith(lowerPath, ".trc")) {
466
                     //if (m_tombraider.checkMime(fullPathMap) == 0) {
468
                     //if (m_tombraider.checkMime(fullPathMap) == 0) {
467
-                        // printf("Validated pak: '%s'\n", fullPathMap);
469
+                        // mConsole->print("Validated pak: '%s'", fullPathMap);
468
 
470
 
469
                         // Just load relative filename
471
                         // Just load relative filename
470
                         mMapList.push_back(bufferString("%s", (fullPathMap + strlen(mPakDir))));
472
                         mMapList.push_back(bufferString("%s", (fullPathMap + strlen(mPakDir))));
471
                     //} else {
473
                     //} else {
472
-                    //    printf("ERROR: pak file '%s' not found or invalid\n", fullPathMap);
474
+                    //    mConsole->print("ERROR: pak file '%s' not found or invalid", fullPathMap);
473
                     //}
475
                     //}
474
                 }
476
                 }
475
 
477
 
479
         }
481
         }
480
         closedir(pakDir);
482
         closedir(pakDir);
481
     } else {
483
     } else {
482
-        printf("Could not open PAK dir %s!\n", dir);
484
+        mConsole->print("Could not open PAK dir %s!", dir);
483
     }
485
     }
484
 }
486
 }
485
 
487
 

+ 2
- 2
src/main.cpp 查看文件

63
 
63
 
64
     // Create globals
64
     // Create globals
65
     atexit(cleanupHandler);
65
     atexit(cleanupHandler);
66
-    printf("Initializing " VERSION "\n");
66
+    printf("Initializing %s", VERSION);
67
     gOpenRaider = new OpenRaider();
67
     gOpenRaider = new OpenRaider();
68
 
68
 
69
     // Try to load a configuration
69
     // Try to load a configuration
80
     gOpenRaider->initialize();
80
     gOpenRaider->initialize();
81
 
81
 
82
     // Enter Main loop
82
     // Enter Main loop
83
-    printf("Starting " VERSION "\n");
83
+    gOpenRaider->mConsole->print("Starting %s", VERSION);
84
     gOpenRaider->run();
84
     gOpenRaider->run();
85
 
85
 
86
     return 0;
86
     return 0;

+ 10
- 5
src/utils/strings.cpp 查看文件

97
     int sz = 60;
97
     int sz = 60;
98
     int n;
98
     int n;
99
     char *text;
99
     char *text;
100
+    va_list tmp;
100
 
101
 
101
     assert(string != NULL);
102
     assert(string != NULL);
102
     assert(string[0] != '\0');
103
     assert(string[0] != '\0');
103
 
104
 
104
     text = new char[sz];
105
     text = new char[sz];
105
 
106
 
106
-    n = vsnprintf(text, sz, string, args);
107
+    va_copy(tmp, args);
108
+    n = vsnprintf(text, sz, string, tmp);
109
+    va_end(tmp);
107
 
110
 
108
     if (n < 0) {
111
     if (n < 0) {
109
         delete [] text;
112
         delete [] text;
111
     } else if (n >= sz) {
114
     } else if (n >= sz) {
112
         sz = n + 1; // buffer too small
115
         sz = n + 1; // buffer too small
113
         delete [] text;
116
         delete [] text;
114
-        text = new char[sz];
115
-        n = vsnprintf(text, sz, string, args);
117
+        text = new char[sz + 1];
118
+        va_copy(tmp, args);
119
+        n = vsnprintf(text, sz, string, tmp);
120
+        va_end(tmp);
116
     }
121
     }
117
 
122
 
118
     return text;
123
     return text;
188
     // Make sure ends in "end" char
193
     // Make sure ends in "end" char
189
     if ((lenPath > 0) && (end != 0) && (dir[lenPath - 1] != end)) {
194
     if ((lenPath > 0) && (end != 0) && (dir[lenPath - 1] != end)) {
190
         dir[lenPath] = end;
195
         dir[lenPath] = end;
191
-        dir[lenPath + 1] = 0;
196
+        dir[lenPath + 1] = '\0';
192
     } else {
197
     } else {
193
-        dir[lenPath] = 0;
198
+        dir[lenPath] = '\0';
194
     }
199
     }
195
 
200
 
196
     return dir;
201
     return dir;

正在加载...
取消
保存