diff options
author | Darkvater <darkvater@openttd.org> | 2005-04-24 21:44:45 +0000 |
---|---|---|
committer | Darkvater <darkvater@openttd.org> | 2005-04-24 21:44:45 +0000 |
commit | a1143a53f0cbe067a9c039e5722b8c8319faa330 (patch) | |
tree | 36c4fec15cf9ecae7501427037ae46c118a36e27 | |
parent | 11dc0e1777d6d8450e4116033cb306b9c76686af (diff) | |
download | openttd-a1143a53f0cbe067a9c039e5722b8c8319faa330.tar.xz |
(svn r2229) - Fix: [ 1188777 ] Non-existing sprite #5125 (presignal). The DOS grf file trgi.grf has 6 less sprites than the windows one. This results in some segfaults for certain sprites. Fixed it by added a dummy grf file consisting ofr 6 sprites and loaded when using DOS gfx at the appropiate place.
-rw-r--r-- | console.c | 535 | ||||
-rw-r--r-- | data/dosdummy.grf | bin | 0 -> 90 bytes | |||
-rw-r--r-- | spritecache.c | 2 | ||||
-rw-r--r-- | table/files.h | 14 |
4 files changed, 378 insertions, 173 deletions
@@ -16,12 +16,13 @@ #include "network_server.h" #define ICON_BUFFER 79 -#define ICON_CMDBUF_SIZE 20 +#define ICON_HISTORY_SIZE 20 #define ICON_CMDLN_SIZE 255 #define ICON_LINE_HEIGHT 12 #define ICON_RIGHT_BORDERWIDTH 10 #define ICON_BOTTOM_BORDERWIDTH 12 #define ICON_MAX_ALIAS_LINES 40 +#define ICON_TOKEN_COUNT 20 // ** main console ** // static Window *_iconsole_win; // Pointer to console window @@ -37,8 +38,8 @@ bool _stdlib_con_developer = false; FILE* _iconsole_output_file; // ** main console cmd buffer -static char* _iconsole_cmdbuffer[ICON_CMDBUF_SIZE]; -static byte _iconsole_cmdbufferpos; +static char *_iconsole_history[ICON_HISTORY_SIZE]; +static byte _iconsole_historypos; /* *************** */ /* end of header */ @@ -54,10 +55,12 @@ static void IConsoleClearCommand(void) SetWindowDirty(_iconsole_win); } +static inline void IConsoleResetHistoryPos(void) {_iconsole_historypos = ICON_HISTORY_SIZE - 1;} + // ** console window ** // static void IConsoleWndProc(Window* w, WindowEvent* e) { - switch(e->event) { + switch (e->event) { case WE_PAINT: { int i = _iconsole_scroll; int max = (w->height / ICON_LINE_HEIGHT) - 1; @@ -93,11 +96,11 @@ static void IConsoleWndProc(Window* w, WindowEvent* e) e->keypress.cont = false; switch (e->keypress.keycode) { case WKC_UP: - IConsoleCmdBufferNavigate(+1); + IConsoleHistoryNavigate(+1); SetWindowDirty(w); break; case WKC_DOWN: - IConsoleCmdBufferNavigate(-1); + IConsoleHistoryNavigate(-1); SetWindowDirty(w); break; case WKC_SHIFT | WKC_PAGEUP: @@ -133,8 +136,7 @@ static void IConsoleWndProc(Window* w, WindowEvent* e) break; case WKC_RETURN: case WKC_NUM_ENTER: IConsolePrintF(_iconsole_color_commands, "] %s", _iconsole_cmdline.buf); - _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; - IConsoleCmdBufferAdd(_iconsole_cmdline.buf); + IConsoleHistoryAdd(_iconsole_cmdline.buf); IConsoleCmdExec(_iconsole_cmdline.buf); IConsoleClearCommand(); @@ -145,23 +147,28 @@ static void IConsoleWndProc(Window* w, WindowEvent* e) MarkWholeScreenDirty(); break; case (WKC_CTRL | 'V'): - if (InsertTextBufferClipboard(&_iconsole_cmdline)) + if (InsertTextBufferClipboard(&_iconsole_cmdline)) { + IConsoleResetHistoryPos(); SetWindowDirty(w); + } break; case WKC_BACKSPACE: case WKC_DELETE: - if (DeleteTextBufferChar(&_iconsole_cmdline, e->keypress.keycode)) + if (DeleteTextBufferChar(&_iconsole_cmdline, e->keypress.keycode)) { + IConsoleResetHistoryPos(); SetWindowDirty(w); - _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; + } break; case WKC_LEFT: case WKC_RIGHT: case WKC_END: case WKC_HOME: - if (MoveTextBufferPos(&_iconsole_cmdline, e->keypress.keycode)) + if (MoveTextBufferPos(&_iconsole_cmdline, e->keypress.keycode)) { + IConsoleResetHistoryPos(); SetWindowDirty(w); + } break; default: if (IsValidAsciiChar(e->keypress.ascii)) { _iconsole_scroll = ICON_BUFFER; InsertTextBufferChar(&_iconsole_cmdline, e->keypress.ascii); - _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; + IConsoleResetHistoryPos(); SetWindowDirty(w); } else e->keypress.cont = true; @@ -193,7 +200,7 @@ void IConsoleInit(void) _iconsole_color_debug = 5; _iconsole_color_commands = 2; _iconsole_scroll = ICON_BUFFER; - _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; + _iconsole_historypos = ICON_HISTORY_SIZE - 1; _iconsole_inited = true; _iconsole_mode = ICONSOLE_CLOSED; _iconsole_win = NULL; @@ -202,19 +209,19 @@ void IConsoleInit(void) _redirect_console_to_client = 0; #endif - memset(_iconsole_cmdbuffer, 0, sizeof(_iconsole_cmdbuffer)); + memset(_iconsole_history, 0, sizeof(_iconsole_history)); memset(_iconsole_buffer, 0, sizeof(_iconsole_buffer)); memset(_iconsole_cbuffer, 0, sizeof(_iconsole_cbuffer)); _iconsole_cmdline.buf = calloc(ICON_CMDLN_SIZE, sizeof(*_iconsole_cmdline.buf)); // create buffer and zero it _iconsole_cmdline.maxlength = ICON_CMDLN_SIZE - 1; IConsoleStdLibRegister(); - IConsolePrintF(13, "OpenTTD Game Console Revision 6 - %s", _openttd_revision); - IConsolePrint(12, "---------------------------------"); - IConsolePrint(12, "use \"help\" for more info"); - IConsolePrint(12, ""); + IConsolePrintF(13, "OpenTTD Game Console Revision 7 - %s", _openttd_revision); + IConsolePrint(12, "------------------------------------"); + IConsolePrint(12, "use \"help\" for more info"); + IConsolePrint(12, ""); IConsoleClearCommand(); - IConsoleCmdBufferAdd(""); + IConsoleHistoryAdd(""); } void IConsoleClear(void) @@ -256,7 +263,6 @@ void IConsoleFree(void) void IConsoleResize(void) { - _iconsole_win = FindWindowById(WC_CONSOLE, 0); switch (_iconsole_mode) { @@ -269,7 +275,7 @@ void IConsoleResize(void) _iconsole_win->width = _screen.width; break; default: - break; + NOT_REACHED(); } MarkWholeScreenDirty(); @@ -283,7 +289,7 @@ void IConsoleSwitch(void) _iconsole_win->height = _screen.height / 3; _iconsole_win->width = _screen.width; _iconsole_mode = ICONSOLE_OPENED; - SETBIT(_no_scroll, SCROLL_CON); + SETBIT(_no_scroll, SCROLL_CON); // override cursor arrows; the gamefield will not scroll break; case ICONSOLE_OPENED: case ICONSOLE_FULL: DeleteWindowById(WC_CONSOLE, 0); @@ -306,34 +312,44 @@ void IConsoleOpen(void) if (_iconsole_mode == ICONSOLE_CLOSED) IConsoleSwitch(); } -void IConsoleCmdBufferAdd(const char* cmd) +/** + * Add the entered line into the history so you can look it back + * scroll, etc. Put it to the beginning as it is the latest text + * @param cmd Text to be entered into the 'history' + */ +void IConsoleHistoryAdd(const char *cmd) { - int i; - if (_iconsole_cmdbufferpos != (ICON_CMDBUF_SIZE - 1)) return; - free(_iconsole_cmdbuffer[ICON_CMDBUF_SIZE - 2]); - for (i = (ICON_CMDBUF_SIZE - 2); i > 0; i--) _iconsole_cmdbuffer[i] = _iconsole_cmdbuffer[i - 1]; - _iconsole_cmdbuffer[0] = strdup(cmd); + free(_iconsole_history[ICON_HISTORY_SIZE - 1]); + + memmove(&_iconsole_history[1], &_iconsole_history[0], sizeof(_iconsole_history[0]) * (ICON_HISTORY_SIZE - 1)); + _iconsole_history[0] = strdup(cmd); + IConsoleResetHistoryPos(); } -void IConsoleCmdBufferNavigate(signed char direction) +/** + * Navigate Up/Down in the history of typed commands + * @param direction Go further back in history (+1), go to recently typed commands (-1) + */ +void IConsoleHistoryNavigate(signed char direction) { - int i; - i = _iconsole_cmdbufferpos + direction; - if (i < 0) i = ICON_CMDBUF_SIZE - 1; - if (i >= ICON_CMDBUF_SIZE) i = 0; + int i = _iconsole_historypos + direction; + + // watch out for overflows, just wrap around + if (i < 0) i = ICON_HISTORY_SIZE - 1; + if (i >= ICON_HISTORY_SIZE) i = 0; + if (direction > 0) - while (_iconsole_cmdbuffer[i] == NULL) { - i++; - if (i >= ICON_CMDBUF_SIZE) i = 0; - } - if (direction < 0) - while (_iconsole_cmdbuffer[i] == NULL) { - --i; - if (i < 0) i = ICON_CMDBUF_SIZE - 1; - } - _iconsole_cmdbufferpos = i; + if (_iconsole_history[i] == NULL) i = 0; + + if (direction < 0) { + while (i > 0 && _iconsole_history[i] == NULL) i--; + } + + _iconsole_historypos = i; IConsoleClearCommand(); - ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_cmdbuffer[i], _iconsole_cmdline.maxlength); + // copy history to 'command prompt / bash' + assert(_iconsole_history[i] != NULL && IS_INT_INSIDE(i, 0, ICON_HISTORY_SIZE)); + ttd_strlcpy(_iconsole_cmdline.buf, _iconsole_history[i], _iconsole_cmdline.maxlength); UpdateTextBufferSize(&_iconsole_cmdline); } @@ -384,173 +400,276 @@ void IConsolePrint(uint16 color_code, const char* string) if (_iconsole_win != NULL) SetWindowDirty(_iconsole_win); } - +/** + * Handle the printing of text entered into the console or redirected there + * by any other means. Uses printf() style format, for more information look + * at @IConsolePrint() + */ void CDECL IConsolePrintF(uint16 color_code, const char* s, ...) { va_list va; - char buf[1024]; - int len; + char buf[ICON_MAX_STREAMSIZE]; va_start(va, s); - len = vsnprintf(buf, sizeof(buf), s, va); + vsnprintf(buf, sizeof(buf), s, va); va_end(va); IConsolePrint(color_code, buf); } +/** + * It is possible to print debugging information to the console, + * which is achieved by using this function. Can only be used by + * @debug() in debug.c. You need at least a level 2 (developer) for debugging + * messages to show up + */ void IConsoleDebug(const char* string) { if (_stdlib_developer > 1) IConsolePrintF(_iconsole_color_debug, "dbg: %s", string); } -void IConsoleError(const char* string) -{ - if (_stdlib_developer > 0) - IConsolePrintF(_iconsole_color_error, "ERROR: %s", string); -} - +/** + * It is possible to print warnings to the console. These are mostly + * errors or mishaps, but non-fatal. You need at least a level 1 (developer) for + * debugging messages to show up + */ void IConsoleWarning(const char* string) { if (_stdlib_developer > 0) IConsolePrintF(_iconsole_color_warning, "WARNING: %s", string); } -void IConsoleCmdRegister(const char* name, _iconsole_cmd_addr addr) +/** + * It is possible to print error information to the console. This can include + * game errors, or errors in general you would want the user to notice + */ +void IConsoleError(const char* string) { - char* _new; - _iconsole_cmd* item; - _iconsole_cmd* item_new; - _iconsole_cmd* item_before; - - _new = strdup(name); + IConsolePrintF(_iconsole_color_error, "ERROR: %s", string); +} - item_new = malloc(sizeof(_iconsole_cmd)); +/** + * Register a new command to be used in the console + * @param name name of the command that will be used + * @param addr function that will be called upon execution of command + */ +void IConsoleCmdRegister(const char *name, IConsoleCmdAddr addr) +{ + IConsoleCmd *item, *item_before; + char *new_cmd = strdup(name); + IConsoleCmd *item_new = malloc(sizeof(IConsoleCmd)); item_new->_next = NULL; item_new->addr = addr; - item_new->name = _new; + item_new->name = new_cmd; item_new->hook_access = NULL; item_new->hook_after_exec = NULL; item_new->hook_before_exec = NULL; + // first command + if (_iconsole_cmds == NULL) { + _iconsole_cmds = item_new; + return; + } + item_before = NULL; item = _iconsole_cmds; - if (item == NULL) { - _iconsole_cmds = item_new; - } else { - while ((item->_next != NULL) && (strcmp(item->name,item_new->name)<=0)) { - item_before = item; - item = item->_next; - } -// insertion sort - if (item_before==NULL) { - if (strcmp(item->name,item_new->name)<=0) { - // appending - item ->_next = item_new; - } else { - // inserting as startitem - _iconsole_cmds = item_new; - item_new ->_next = item; - } - } else { - if (strcmp(item->name,item_new->name)<=0) { - // appending - item ->_next = item_new; - } else { - // inserting - item_new ->_next = item_before->_next; - item_before ->_next = item_new; - } + /* BEGIN - Alphabetically insert the commands into the linked list */ + while (item != NULL) { + int i = strcmp(item->name, item_new->name); + if (i == 0) { + IConsoleError("a command with this name already exists; insertion aborted"); + free(item_new); + return; } -// insertion sort end + + if (i > 0) break; // insert at this position + + item_before = item; + item = item->_next; } + if (item_before == NULL) { + _iconsole_cmds = item_new; + } else + item_before->_next = item_new; + + item_new->_next = item; + /* END - Alphabetical insert */ } -_iconsole_cmd* IConsoleCmdGet(const char* name) +/** + * Find the command pointed to by its string + * @param name command to be found + * @return return Cmdstruct of the found command, or NULL on failure + */ +IConsoleCmd *IConsoleCmdGet(const char *name) { - _iconsole_cmd* item; + IConsoleCmd *item; - item = _iconsole_cmds; - while (item != NULL) { + for (item = _iconsole_cmds; item != NULL; item = item->_next) { if (strcmp(item->name, name) == 0) return item; - item = item->_next; } return NULL; } -void IConsoleAliasRegister(const char* name, const char* cmdline) +/** + * Register a an alias for an already existing command in the console + * @param name name of the alias that will be used + * @param cmd name of the command that 'name' will be alias of + */ +void IConsoleAliasRegister(const char *name, const char *cmd) { - char* _new; - char* _newcmd; - _iconsole_alias* item; - _iconsole_alias* item_new; - _iconsole_alias* item_before; - - _new = strdup(name); - _newcmd = strdup(cmdline); - - item_new = malloc(sizeof(_iconsole_alias)); + IConsoleAlias *item, *item_before; + char *new_alias = strdup(name); + char *cmd_aliased = strdup(cmd); + IConsoleAlias *item_new = malloc(sizeof(IConsoleAlias)); item_new->_next = NULL; - item_new->cmdline = _newcmd; - item_new->name = _new; + item_new->cmdline = cmd_aliased; + item_new->name = new_alias; item_before = NULL; item = _iconsole_aliases; - if (item == NULL) { + // first command + if (_iconsole_aliases == NULL) { _iconsole_aliases = item_new; - } else { - while ((item->_next != NULL) && (strcmp(item->name,item_new->name)<=0)) { - item_before = item; - item = item->_next; - } -// insertion sort - if (item_before==NULL) { - if (strcmp(item->name,item_new->name)<=0) { - // appending - item ->_next = item_new; - } else { - // inserting as startitem - _iconsole_aliases = item_new; - item_new ->_next = item; - } - } else { - if (strcmp(item->name,item_new->name)<=0) { - // appending - item ->_next = item_new; - } else { - // inserting - item_new ->_next = item_before->_next; - item_before ->_next = item_new; - } + return; + } + + item_before = NULL; + item = _iconsole_aliases; + + /* BEGIN - Alphabetically insert the commands into the linked list */ + while (item != NULL) { + int i = strcmp(item->name, item_new->name); + if (i == 0) { + IConsoleError("an alias with this name already exists; insertion aborted"); + free(item_new); + return; } -// insertion sort end + + if (i > 0) break; // insert at this position + + item_before = item; + item = item->_next; } + if (item_before == NULL) { + _iconsole_aliases = item_new; + } else + item_before->_next = item_new; + + item_new->_next = item; + /* END - Alphabetical insert */ } -_iconsole_alias* IConsoleAliasGet(const char* name) +/** + * Find the alias pointed to by its string + * @param name alias to be found + * @return return Aliasstruct of the found alias, or NULL on failure + */ +IConsoleAlias *IConsoleAliasGet(const char *name) { - _iconsole_alias* item; + IConsoleAlias* item; - item = _iconsole_aliases; - while (item != NULL) { + for (item = _iconsole_aliases; item != NULL; item = item->_next) { if (strcmp(item->name, name) == 0) return item; - item = item->_next; } + return NULL; } -static void IConsoleAliasExec(const char* cmdline, char* tokens[20], byte tokentypes[20]) +static inline int IConsoleCopyInParams(char *dst, const char *src, uint bufpos) { - char* lines[ICON_MAX_ALIAS_LINES]; - char* linestream; - char* linestream_s; + int len = min(ICON_MAX_STREAMSIZE - bufpos, strlen(src)); + strncpy(dst, src, len); + + return len; +} + +/** + * An alias is just another name for a command, or for more commands + * Execute it as well. + * @param cmdstr is the alias of the command + * @param tokens are the parameters given to the original command (0 is the first param) + * @param tokencount the number of parameters passed + */ +static void IConsoleAliasExec(const char *cmdstr, char *tokens[ICON_TOKEN_COUNT], int tokencount) +{ + const char *cmdptr; + char *aliases[ICON_MAX_ALIAS_LINES], aliasstream[ICON_MAX_STREAMSIZE]; + int i; + uint a_index, astream_i; + + memset(&aliases, 0, sizeof(aliases)); + memset(&aliasstream, 0, sizeof(aliasstream)); + + aliases[0] = aliasstream; + for (cmdptr = cmdstr, a_index = 0, astream_i = 0; *cmdptr != '\0'; *cmdptr++) { + if (a_index >= lengthof(aliases) || astream_i >= lengthof(aliasstream)) break; + + switch (*cmdptr) { + case '\'': /* ' will double for : */ + aliasstream[astream_i++] = '"'; + break; + case ';': /* Cmd seperator, start new line */ + aliasstream[astream_i] = '\0'; + aliases[++a_index] = &aliasstream[++astream_i]; + *cmdptr++; + break; + case '%': /* One specific parameter: %A = [param 1] %B = [param 2] ... */ + *cmdptr++; + switch (*cmdptr) { + case '+': { /* All parameters seperated: "[param 1]" "[param 2]" */ + for (i = 0; i != tokencount; i++) { + aliasstream[astream_i++] = '"'; + astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i); + aliasstream[astream_i++] = '"'; + aliasstream[astream_i++] = ' '; + } + } break; + case '!': { /* Merge the parameters to one: "[param 1] [param 2] [param 3...]" */ + aliasstream[astream_i++] = '"'; + for (i = 0; i != tokencount; i++) { + astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[i], astream_i); + aliasstream[astream_i++] = ' '; + } + aliasstream[astream_i++] = '"'; + + } break; + default: { + int param = *cmdptr - 'A'; + + if (param < 0 || param >= tokencount) { + IConsoleError("too many or wrong amount of parameters passed to alias, aborting"); + return; + } + + aliasstream[astream_i++] = '"'; + astream_i += IConsoleCopyInParams(&aliasstream[astream_i], tokens[param], astream_i); + aliasstream[astream_i++] = '"'; + } break; + } break; + + default: + aliasstream[astream_i++] = *cmdptr; + break; + } + } + + for (i = 0; i <= (int)a_index; i++) IConsoleCmdExec(aliases[i]); +} + +#if 0 +static void IConsoleAliasExec(const char* cmdline, char* tokens[TOKEN_COUNT], byte tokentypes[TOKEN_COUNT]) +{ + char *lines[ICON_MAX_ALIAS_LINES]; + char *linestream, *linestream_s; int c; int i; @@ -558,13 +677,10 @@ static void IConsoleAliasExec(const char* cmdline, char* tokens[20], byte tokent int x; byte t; - //** clearing buffer **// + memset(lines, 0, ICON_MAX_ALIAS_LINES); // clear buffer - for (i = 0; i < 40; i++) { - lines[0] = NULL; - } - linestream_s = linestream = malloc(1024*ICON_MAX_ALIAS_LINES); - memset(linestream, 0, 1024*ICON_MAX_ALIAS_LINES); + linestream_s = linestream = malloc(1024 * ICON_MAX_ALIAS_LINES); + memset(linestream, 0, 1024 * ICON_MAX_ALIAS_LINES); //** parsing **// @@ -669,12 +785,13 @@ static void IConsoleAliasExec(const char* cmdline, char* tokens[20], byte tokent *linestream = '\0'; } - for (i=0; i<c; i++) { - IConsoleCmdExec(lines[i]); - } + for (i = 0; i < c; i++) IConsoleCmdExec(lines[i]); free(linestream_s); } +#endif + +static void IConsoleVarExec(char *token[ICON_TOKEN_COUNT]) {} void IConsoleVarInsert(_iconsole_var* item_new, const char* name) { @@ -777,8 +894,10 @@ void IConsoleVarMemRegister(const char* name, _iconsole_var_types type) _iconsole_var* IConsoleVarGet(const char* name) { _iconsole_var* item; - for (item = _iconsole_vars; item != NULL; item = item->_next) + for (item = _iconsole_vars; item != NULL; item = item->_next) { if (strcmp(item->name, name) == 0) return item; + } + return NULL; } @@ -985,7 +1104,7 @@ bool IConsoleVarHookHandle(_iconsole_var* hook_var, _iconsole_hook_types type) void IConsoleCmdHook(const char* name, _iconsole_hook_types type, iconsole_cmd_hook proc) { - _iconsole_cmd* hook_cmd = IConsoleCmdGet(name); + IConsoleCmd* hook_cmd = IConsoleCmdGet(name); if (hook_cmd == NULL) return; switch (type) { case ICONSOLE_HOOK_AFTER_EXEC: @@ -1004,7 +1123,7 @@ void IConsoleCmdHook(const char* name, _iconsole_hook_types type, iconsole_cmd_h } } -bool IConsoleCmdHookHandle(_iconsole_cmd* hook_cmd, _iconsole_hook_types type) +bool IConsoleCmdHookHandle(IConsoleCmd* hook_cmd, _iconsole_hook_types type) { iconsole_cmd_hook proc = NULL; switch (type) { @@ -1025,9 +1144,96 @@ bool IConsoleCmdHookHandle(_iconsole_cmd* hook_cmd, _iconsole_hook_types type) return proc == NULL ? true : proc(hook_cmd); } +/** + * Execute a given command passed to us. First chop it up into + * individual tokens, then execute it if possible + * @param cmdstr string to be parsed and executed + */ +void IConsoleCmdExec(const char *cmdstr) +{ + IConsoleCmd *cmd = NULL; + IConsoleAlias *alias = NULL; + _iconsole_var *var = NULL; + + const char *cmdptr; + char *tokens[ICON_TOKEN_COUNT], tokenstream[ICON_MAX_STREAMSIZE]; + uint t_index, tstream_i; + + bool longtoken = false; + + for (cmdptr = cmdstr; *cmdptr != '\0'; *cmdptr++) { + if (!IsValidAsciiChar(*cmdptr)) { + IConsoleError("command contains malformed characters, aborting"); + return; + } + } + + if (_stdlib_con_developer) + IConsolePrintF(_iconsole_color_debug, "condbg: executing cmdline: %s", cmdstr); + + memset(&tokens, 0, sizeof(tokens)); + memset(&tokenstream, 0, sizeof(tokenstream)); + + /* 1. Split up commandline into tokens, seperated by spaces, commands + * enclosed in "" are taken as one token. We can only go as far as the amount + * of characters in our stream or the max amount of tokens we can handle */ + tokens[0] = tokenstream; + for (cmdptr = cmdstr, t_index = 0, tstream_i = 0; *cmdptr != '\0'; *cmdptr++) { + if (t_index >= lengthof(tokens) || tstream_i >= lengthof(tokenstream)) break; + + switch (*cmdptr) { + case ' ': /* Token seperator */ + if (!longtoken) { + tokenstream[tstream_i] = '\0'; + tokens[++t_index] = &tokenstream[tstream_i + 1]; + } else + tokenstream[tstream_i] = *cmdptr; + + tstream_i++; + break; + case '"': /* Tokens enclosed in "" are one token */ + longtoken = !longtoken; + break; + default: /* Normal character */ + tokenstream[tstream_i++] = *cmdptr; + break; + } + } + + t_index++; // index was 0 + + /* 2. Determine type of command (cmd, alias or variable) and execute + * First try commands, then aliases, and finally variables + */ + cmd = IConsoleCmdGet(tokens[0]); + if (cmd != NULL) { + if (IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_ACCESS)) { + IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_BEFORE_EXEC); + cmd->addr(t_index, tokens, NULL); + IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_AFTER_EXEC); + } + return; + } + + alias = IConsoleAliasGet(tokens[0]); + if (alias != NULL) { + IConsoleAliasExec(alias->cmdline, &tokens[1], t_index - 1); + return; + } + + var = IConsoleVarGet(tokens[0]); + if (var != NULL) { + IConsoleVarExec(tokens); + return; + } + + IConsoleError("command or variable not found"); +} + +#if 0 void IConsoleCmdExec(const char* cmdstr) { - _iconsole_cmd_addr function; + IConsoleCmdAddr function; char* tokens[20]; byte tokentypes[20]; char* tokenstream; @@ -1035,8 +1241,8 @@ void IConsoleCmdExec(const char* cmdstr) byte execution_mode; _iconsole_var* var = NULL; _iconsole_var* result = NULL; - _iconsole_cmd* cmd = NULL; - _iconsole_alias* alias = NULL; + IConsoleCmd* cmd = NULL; + IConsoleAlias* alias = NULL; bool longtoken; bool valid_token; @@ -1046,14 +1252,10 @@ void IConsoleCmdExec(const char* cmdstr) uint i; uint l; - for (; strchr("\n\r \t", *cmdstr) != NULL; ++cmdstr) { + for (; strchr("\n\r \t", *cmdstr) != NULL; cmdstr++) { switch (*cmdstr) { - case '\0': - case '#': - return; - - default: - break; + case '\0': case '#': return; + default: break; } } @@ -1484,3 +1686,4 @@ void IConsoleCmdExec(const char* cmdstr) //** freeing the tokenstream **// free(tokenstream_s); } +#endif diff --git a/data/dosdummy.grf b/data/dosdummy.grf Binary files differnew file mode 100644 index 000000000..6524d5971 --- /dev/null +++ b/data/dosdummy.grf diff --git a/spritecache.c b/spritecache.c index af63ef8c3..125b1e906 100644 --- a/spritecache.c +++ b/spritecache.c @@ -70,7 +70,7 @@ typedef struct MD5File { } MD5File; typedef struct FileList { - const MD5File basic[4]; // grf files that always have to be loaded + const MD5File basic[5]; // grf files that always have to be loaded const MD5File landscape[3]; // landscape specific grf files } FileList; diff --git a/table/files.h b/table/files.h index c97cfcf06..7b3b91c89 100644 --- a/table/files.h +++ b/table/files.h @@ -23,9 +23,10 @@ FileList files_dos = { { - { "TRG1.GRF", {0x93,0x11,0x67,0x62,0x80,0xe5,0xb1,0x40,0x77,0xa8,0xee,0x41,0xc1,0xb4,0x21,0x92} }, - { "TRGI.GRF", {0xda,0x6a,0x6c,0x9d,0xcc,0x45,0x1e,0xec,0x88,0xd7,0x92,0x11,0x43,0x7b,0x76,0xa8} }, - { "signalsw.grf", {0x76,0x1b,0x42,0x25,0x44,0x0d,0x21,0xc7,0xe0,0xb4,0x25,0xd8,0x2f,0xc8,0x52,0x38} }, //0x1320 - 0x1405 inclusive + { "TRG1.GRF", {0x93,0x11,0x67,0x62,0x80,0xe5,0xb1,0x40,0x77,0xa8,0xee,0x41,0xc1,0xb4,0x21,0x92} }, // 0 - 4792 inclusive + { "TRGI.GRF", {0xda,0x6a,0x6c,0x9d,0xcc,0x45,0x1e,0xec,0x88,0xd7,0x92,0x11,0x43,0x7b,0x76,0xa8} }, // 4793 - 4889 inclusive + { "dosdummy.grf", {0x07,0x01,0xe6,0xc4,0x07,0x6a,0x5b,0xc3,0xf4,0x9f,0x01,0xad,0x21,0x6c,0xa0,0xc2} }, // 4890 - 4895 inclusive + { "signalsw.grf", {0x76,0x1b,0x42,0x25,0x44,0x0d,0x21,0xc7,0xe0,0xb4,0x25,0xd8,0x2f,0xc8,0x52,0x38} }, // 4896 - 5125 inclusive { NULL, { 0 } } }, { { "TRGC.GRF", {0xed,0x44,0x66,0x37,0xe0,0x34,0x10,0x4c,0x55,0x59,0xb3,0x2c,0x18,0xaf,0xe7,0x8d} }, @@ -36,9 +37,10 @@ FileList files_dos = { FileList files_win = { { - { "TRG1R.GRF", {0xb0,0x4c,0xe5,0x93,0xd8,0xc5,0x01,0x6e,0x07,0x47,0x3a,0x74,0x3d,0x7d,0x33,0x58} }, - { "TRGIR.GRF", {0x0c,0x24,0x84,0xff,0x6b,0xe4,0x9f,0xc6,0x3a,0x83,0xbe,0x6a,0xb5,0xc3,0x8f,0x32} }, - { "signalsw.grf", {0x76,0x1b,0x42,0x25,0x44,0x0d,0x21,0xc7,0xe0,0xb4,0x25,0xd8,0x2f,0xc8,0x52,0x38} }, //0x1320 - 0x1405 inclusive + { "TRG1R.GRF", {0xb0,0x4c,0xe5,0x93,0xd8,0xc5,0x01,0x6e,0x07,0x47,0x3a,0x74,0x3d,0x7d,0x33,0x58} }, // 0 - 4792 inclusive + { "TRGIR.GRF", {0x0c,0x24,0x84,0xff,0x6b,0xe4,0x9f,0xc6,0x3a,0x83,0xbe,0x6a,0xb5,0xc3,0x8f,0x32} }, // 4793 - 4895 inclusive + { "signalsw.grf", {0x76,0x1b,0x42,0x25,0x44,0x0d,0x21,0xc7,0xe0,0xb4,0x25,0xd8,0x2f,0xc8,0x52,0x38} }, // 4896 - 5125 inclusive + { NULL, { 0 } }, { NULL, { 0 } } }, { { "TRGCR.GRF", {0x36,0x68,0xf4,0x10,0xc7,0x61,0xa0,0x50,0xb5,0xe7,0x09,0x5a,0x2b,0x14,0x87,0x9b} }, |