darkvater@135: #include "stdafx.h" darkvater@135: #include "ttd.h" darkvater@135: #include "window.h" darkvater@135: #include "gui.h" darkvater@135: #include "gfx.h" darkvater@135: #include "player.h" darkvater@135: #include "variables.h" darkvater@135: #include "hal.h" darkvater@135: #include darkvater@289: #include signde@274: #include "console.h" signde@274: signde@274: #ifdef WIN32 signde@274: #include signde@273: #endif darkvater@135: darkvater@301: #define ICON_BUFFER 79 darkvater@301: #define ICON_CMDBUF_SIZE 20 darkvater@301: #define ICON_CMDLN_SIZE 255 darkvater@301: #define ICON_LINE_HEIGHT 12 darkvater@289: darkvater@289: typedef enum { darkvater@289: ICONSOLE_OPENED, darkvater@289: ICONSOLE_CLOSED darkvater@289: } _iconsole_modes; darkvater@289: darkvater@135: // ** main console ** // darkvater@135: static bool _iconsole_inited; darkvater@301: static char* _iconsole_buffer[ICON_BUFFER + 1]; darkvater@301: static char _iconsole_cbuffer[ICON_BUFFER + 1]; darkvater@301: static char _iconsole_cmdline[ICON_CMDLN_SIZE]; darkvater@135: static byte _iconsole_cmdpos; darkvater@289: static _iconsole_modes _iconsole_mode = ICONSOLE_CLOSED; darkvater@289: static Window* _iconsole_win = NULL; darkvater@135: static byte _iconsole_scroll; darkvater@135: darkvater@135: // ** console cursor ** // darkvater@135: static bool _icursor_state; darkvater@135: static byte _icursor_rate; darkvater@135: static byte _icursor_counter; darkvater@135: signde@220: // ** stdlib ** // darkvater@289: byte _stdlib_developer = 1; darkvater@289: bool _stdlib_con_developer = false; darkvater@289: FILE* _iconsole_output_file; signde@220: darkvater@301: // ** main console cmd buffer darkvater@301: static char* _iconsole_cmdbuffer[ICON_CMDBUF_SIZE]; signde@220: static byte _iconsole_cmdbufferpos; signde@220: darkvater@135: // ** console window ** // darkvater@289: static void IConsoleWndProc(Window* w, WindowEvent* e); darkvater@289: static const Widget _iconsole_window_widgets[] = { darkvater@289: {WIDGETS_END} darkvater@289: }; darkvater@135: static const WindowDesc _iconsole_window_desc = { darkvater@135: 0, 0, 2, 2, darkvater@289: WC_CONSOLE, 0, darkvater@135: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, darkvater@135: _iconsole_window_widgets, darkvater@135: IConsoleWndProc, darkvater@135: }; darkvater@135: darkvater@135: /* *************** */ darkvater@135: /* end of header */ signde@274: /* *************** */ signde@274: darkvater@289: static void IConsoleAppendClipboard(void) signde@274: { signde@274: #ifdef WIN32 signde@274: if (IsClipboardFormatAvailable(CF_TEXT)) { darkvater@289: const char* data; signde@274: HGLOBAL cbuf; signde@274: signde@274: OpenClipboard(NULL); signde@274: cbuf = GetClipboardData(CF_TEXT); darkvater@289: data = GlobalLock(cbuf); signde@274: darkvater@301: /* IS_INT_INSIDE = filter for ascii-function codes like BELL and so on [we need an special filter here later] */ darkvater@301: for (; (IS_INT_INSIDE(*data, ' ', 256)) && (_iconsole_cmdpos < lengthof(_iconsole_cmdline) - 1); ++data) darkvater@301: _iconsole_cmdline[_iconsole_cmdpos++] = *data; signde@274: signde@274: GlobalUnlock(cbuf); signde@274: CloseClipboard(); signde@274: } signde@274: #endif signde@273: } darkvater@135: darkvater@289: static void IConsoleClearCommand(void) darkvater@135: { darkvater@289: memset(_iconsole_cmdline, 0, sizeof(_iconsole_cmdline)); darkvater@289: _iconsole_cmdpos = 0; darkvater@289: SetWindowDirty(_iconsole_win); darkvater@135: } darkvater@135: darkvater@289: static void IConsoleWndProc(Window* w, WindowEvent* e) darkvater@135: { signde@209: // only do window events with the console signde@209: w = FindWindowById(WC_CONSOLE, 0); signde@209: darkvater@135: switch(e->event) { darkvater@289: case WE_PAINT: darkvater@135: { darkvater@289: int i = _iconsole_scroll; darkvater@301: int max = (w->height / ICON_LINE_HEIGHT) - 1; darkvater@289: GfxFillRect(w->left, w->top, w->width, w->height - 1, 0); darkvater@289: while ((i > _iconsole_scroll - max) && (_iconsole_buffer[i] != NULL)) { darkvater@289: DoDrawString(_iconsole_buffer[i], 5, darkvater@301: w->height - (_iconsole_scroll + 2 - i) * ICON_LINE_HEIGHT, _iconsole_cbuffer[i]); darkvater@289: i--; darkvater@135: } darkvater@301: DoDrawString("]", 5, w->height - ICON_LINE_HEIGHT, _iconsole_color_commands); darkvater@301: DoDrawString(_iconsole_cmdline, 10, w->height - ICON_LINE_HEIGHT, _iconsole_color_commands); darkvater@289: break; darkvater@135: } darkvater@289: case WE_TICK: darkvater@289: _icursor_counter++; darkvater@289: if (_icursor_counter > _icursor_rate) { darkvater@135: int posx; darkvater@135: int posy; darkvater@169: darkvater@289: _icursor_state = !_icursor_state; darkvater@135: darkvater@289: _cur_dpi = &_screen; darkvater@289: posx = 10 + GetStringWidth(_iconsole_cmdline); darkvater@289: posy = w->height - 3; darkvater@289: GfxFillRect(posx, posy, posx + 5, posy + 1, _icursor_state ? 14 : 0); darkvater@289: _video_driver->make_dirty(posx, posy, 5, 1); darkvater@289: _icursor_counter = 0; darkvater@289: } darkvater@289: break; darkvater@289: case WE_DESTROY: darkvater@289: _iconsole_win = NULL; darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; darkvater@289: break; darkvater@289: case WE_KEYPRESS: darkvater@289: { darkvater@289: e->keypress.cont = false; darkvater@289: switch (e->keypress.keycode) { darkvater@289: case WKC_CTRL | 'V': darkvater@289: IConsoleAppendClipboard(); darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_UP: darkvater@289: IConsoleCmdBufferNavigate(+1); darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_DOWN: darkvater@289: IConsoleCmdBufferNavigate(-1); darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_PAGEUP: darkvater@301: if (_iconsole_scroll - (w->height / ICON_LINE_HEIGHT) - 1 < 0) darkvater@289: _iconsole_scroll = 0; darkvater@289: else darkvater@301: _iconsole_scroll -= (w->height / ICON_LINE_HEIGHT) - 1; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_PAGEDOWN: darkvater@301: if (_iconsole_scroll + (w->height / ICON_LINE_HEIGHT) - 1 > ICON_BUFFER) darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@289: else darkvater@301: _iconsole_scroll += (w->height / ICON_LINE_HEIGHT) - 1; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_UP: darkvater@289: if (_iconsole_scroll <= 0) darkvater@289: _iconsole_scroll = 0; darkvater@289: else darkvater@289: --_iconsole_scroll; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_SHIFT | WKC_DOWN: darkvater@301: if (_iconsole_scroll >= ICON_BUFFER) darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@289: else darkvater@289: ++_iconsole_scroll; darkvater@289: SetWindowDirty(w); darkvater@289: break; darkvater@289: case WKC_BACKQUOTE: darkvater@289: IConsoleSwitch(); darkvater@289: break; darkvater@289: case WKC_RETURN: darkvater@289: IConsolePrintF(_iconsole_color_commands, "] %s", _iconsole_cmdline); darkvater@289: IConsoleCmdBufferAdd(_iconsole_cmdline); darkvater@289: IConsoleCmdExec(_iconsole_cmdline); darkvater@289: IConsoleClearCommand(); darkvater@289: break; darkvater@289: case WKC_BACKSPACE: darkvater@289: if (_iconsole_cmdpos != 0) _iconsole_cmdpos--; darkvater@289: _iconsole_cmdline[_iconsole_cmdpos] = 0; darkvater@289: SetWindowDirty(w); darkvater@289: _iconsole_cmdbufferpos = 19; darkvater@289: break; darkvater@289: default: darkvater@301: /* IS_INT_INSIDE = filter for ascii-function codes like BELL and so on [we need an special filter here later] */ darkvater@301: if (IS_INT_INSIDE(e->keypress.ascii, ' ', 256)) { darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@289: _iconsole_cmdline[_iconsole_cmdpos] = e->keypress.ascii; darkvater@301: if (_iconsole_cmdpos != lengthof(_iconsole_cmdline)) darkvater@289: _iconsole_cmdpos++; darkvater@289: SetWindowDirty(w); darkvater@301: _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; darkvater@289: } darkvater@289: else darkvater@289: e->keypress.cont = true; darkvater@289: } darkvater@289: break; darkvater@289: } darkvater@135: } darkvater@135: } darkvater@135: darkvater@289: void IConsoleInit(void) darkvater@135: { darkvater@289: uint i; signde@220: #if defined(WITH_REV) signde@220: extern char _openttd_revision[]; signde@220: #endif darkvater@247: _iconsole_output_file = NULL; signde@220: _iconsole_color_default = 1; darkvater@247: _iconsole_color_error = 3; signde@229: _iconsole_color_warning = 13; signde@220: _iconsole_color_debug = 5; signde@220: _iconsole_color_commands = 2; darkvater@301: _iconsole_scroll = ICON_BUFFER; darkvater@301: _iconsole_cmdbufferpos = ICON_CMDBUF_SIZE - 1; darkvater@289: _iconsole_inited = true; darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; darkvater@289: _iconsole_win = NULL; darkvater@289: _icursor_state = false; darkvater@289: _icursor_rate = 5; darkvater@289: _icursor_counter = 0; darkvater@289: for (i = 0; i < lengthof(_iconsole_cmdbuffer); i++) darkvater@289: _iconsole_cmdbuffer[i] = NULL; darkvater@301: for (i = 0; i <= ICON_BUFFER; i++) { darkvater@289: _iconsole_buffer[i] = NULL; darkvater@289: _iconsole_cbuffer[i] = 0; darkvater@289: } signde@220: IConsoleStdLibRegister(); signde@220: #if defined(WITH_REV) darkvater@289: IConsolePrintF(13, "OpenTTD Game Console Revision 4 - %s", _openttd_revision); signde@220: #else darkvater@289: IConsolePrint(13, "OpenTTD Game Console Revision 4"); signde@220: #endif darkvater@289: IConsolePrint(12, "---------------------------------"); darkvater@289: IConsolePrint(12, "use \"help\" for more info"); darkvater@289: IConsolePrint(12, ""); signde@220: IConsoleClearCommand(); signde@220: IConsoleCmdBufferAdd(""); darkvater@135: } darkvater@135: darkvater@289: void IConsoleClear(void) darkvater@135: { darkvater@289: uint i; darkvater@301: for (i = 0; i <= ICON_BUFFER; i++) signde@220: free(_iconsole_buffer[i]); darkvater@135: } darkvater@135: darkvater@289: void IConsoleFree(void) darkvater@135: { darkvater@289: _iconsole_inited = false; signde@220: IConsoleClear(); darkvater@289: if (_iconsole_output_file != NULL) fclose(_iconsole_output_file); darkvater@135: } darkvater@135: darkvater@289: void IConsoleResize(void) signde@220: { darkvater@289: if (_iconsole_win != NULL) { darkvater@135: _iconsole_win->height = _screen.height / 3; darkvater@289: _iconsole_win->width = _screen.width; darkvater@135: } darkvater@135: } darkvater@135: darkvater@289: void IConsoleSwitch(void) darkvater@135: { darkvater@289: switch (_iconsole_mode) { darkvater@289: case ICONSOLE_CLOSED: darkvater@289: _iconsole_win = AllocateWindowDesc(&_iconsole_window_desc); darkvater@289: _iconsole_win->height = _screen.height / 3; darkvater@289: _iconsole_win->width = _screen.width; darkvater@289: _iconsole_mode = ICONSOLE_OPENED; darkvater@289: break; darkvater@289: case ICONSOLE_OPENED: darkvater@289: DeleteWindowById(WC_CONSOLE, 0); darkvater@289: _iconsole_win = NULL; darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; darkvater@289: break; darkvater@289: } darkvater@135: MarkWholeScreenDirty(); darkvater@289: MarkAllViewportsDirty(0, 0, _screen.width, _screen.height); darkvater@289: _video_driver->make_dirty(0, 0, _screen.width, _screen.height); darkvater@135: } darkvater@135: darkvater@289: void IConsoleClose(void) signde@220: { darkvater@289: if (_iconsole_mode == ICONSOLE_OPENED) IConsoleSwitch(); darkvater@289: _iconsole_mode = ICONSOLE_CLOSED; darkvater@135: } darkvater@135: darkvater@289: void IConsoleOpen(void) signde@220: { darkvater@289: if (_iconsole_mode == ICONSOLE_CLOSED) IConsoleSwitch(); darkvater@301: _iconsole_mode = ICONSOLE_OPENED; darkvater@141: } darkvater@141: darkvater@289: void IConsoleCmdBufferAdd(const char* cmd) signde@220: { signde@220: int i; signde@220: if (_iconsole_cmdbufferpos != 19) return; darkvater@289: free(_iconsole_cmdbuffer[18]); darkvater@289: for (i = 18; i > 0; i--) _iconsole_cmdbuffer[i] = _iconsole_cmdbuffer[i - 1]; darkvater@289: _iconsole_cmdbuffer[0] = strdup(cmd); signde@220: } signde@220: signde@220: void IConsoleCmdBufferNavigate(signed char direction) signde@220: { signde@220: int i; darkvater@289: i = _iconsole_cmdbufferpos + direction; darkvater@289: if (i < 0) i = 19; darkvater@289: if (i > 19) i = 0; darkvater@289: if (direction > 0) darkvater@289: while (_iconsole_cmdbuffer[i] == NULL) { darkvater@289: ++i; darkvater@289: if (i > 19) i = 0; signde@220: } darkvater@289: if (direction < 0) darkvater@289: while (_iconsole_cmdbuffer[i] == NULL) { darkvater@289: --i; darkvater@289: if (i < 0) i = 19; signde@220: } signde@220: _iconsole_cmdbufferpos = i; signde@220: IConsoleClearCommand(); darkvater@289: memcpy(_iconsole_cmdline, _iconsole_cmdbuffer[i], darkvater@289: strlen(_iconsole_cmdbuffer[i])); darkvater@289: _iconsole_cmdpos = strlen(_iconsole_cmdbuffer[i]); darkvater@141: } darkvater@141: darkvater@289: void IConsolePrint(byte color_code, const char* string) darkvater@135: { darkvater@289: char* _ex; darkvater@289: char* _new; darkvater@289: char _exc; darkvater@289: char _newc; darkvater@289: char* i; darkvater@289: int j; darkvater@135: signde@220: if (!_iconsole_inited) return; darkvater@135: darkvater@289: _newc = color_code; darkvater@289: _new = strdup(string); signde@220: darkvater@289: for (i = _new; *i != '\0'; ++i) darkvater@301: if (*i < ' ') *i = ' '; /* filter for ascii-function codes like BELL and so on [we need an special filter here later] */ signde@220: darkvater@301: for (j = ICON_BUFFER; j >= 0; --j) { darkvater@289: _ex = _iconsole_buffer[j]; darkvater@289: _exc = _iconsole_cbuffer[j]; darkvater@289: _iconsole_buffer[j] = _new; darkvater@289: _iconsole_cbuffer[j] = _newc; darkvater@289: _new = _ex; darkvater@289: _newc = _exc; darkvater@289: } darkvater@289: free(_ex); darkvater@289: darkvater@289: if (_iconsole_win != NULL) SetWindowDirty(_iconsole_win); darkvater@135: } darkvater@135: darkvater@135: darkvater@289: void CDECL IConsolePrintF(byte color_code, const char* s, ...) darkvater@135: { darkvater@135: va_list va; darkvater@135: char buf[1024]; darkvater@247: int len; darkvater@247: darkvater@135: va_start(va, s); darkvater@289: len = vsnprintf(buf, sizeof(buf), s, va); darkvater@135: va_end(va); darkvater@247: darkvater@289: IConsolePrint(color_code, buf); darkvater@289: darkvater@289: if (_iconsole_output_file != NULL) { darkvater@247: // if there is an console output file ... also print it there darkvater@289: fwrite(buf, len, 1, _iconsole_output_file); darkvater@301: fwrite("\n", 1, 1, _iconsole_output_file); darkvater@289: } darkvater@135: } darkvater@135: darkvater@289: void IConsoleDebug(const char* string) signde@220: { darkvater@289: if (_stdlib_developer > 1) darkvater@289: IConsolePrintF(_iconsole_color_debug, "DEBUG: %s", string); darkvater@247: } darkvater@135: darkvater@289: void IConsoleError(const char* string) signde@220: { darkvater@289: if (_stdlib_developer > 0) darkvater@289: IConsolePrintF(_iconsole_color_error, "ERROR: %s", string); darkvater@289: } darkvater@135: darkvater@289: void IConsoleWarning(const char* string) darkvater@289: { darkvater@289: if (_stdlib_developer > 0) darkvater@289: IConsolePrintF(_iconsole_color_warning, "WARNING: %s", string); darkvater@289: } darkvater@289: darkvater@289: void IConsoleCmdRegister(const char* name, _iconsole_cmd_addr addr) darkvater@289: { darkvater@289: char* _new; darkvater@289: _iconsole_cmd* item; darkvater@289: _iconsole_cmd* item_new; darkvater@289: darkvater@289: _new = strdup(name); darkvater@135: signde@220: item_new = malloc(sizeof(_iconsole_cmd)); darkvater@135: signde@220: item_new->_next = NULL; darkvater@289: item_new->addr = addr; darkvater@289: item_new->name = _new; signde@220: signde@220: item_new->hook_access = NULL; signde@220: item_new->hook_after_exec = NULL; signde@220: item_new->hook_before_exec = NULL; signde@220: signde@220: item = _iconsole_cmds; signde@220: if (item == NULL) { signde@220: _iconsole_cmds = item_new; darkvater@289: } else { darkvater@289: while (item->_next != NULL) item = item->_next; signde@220: item->_next = item_new; darkvater@289: } signde@220: } signde@220: darkvater@289: _iconsole_cmd* IConsoleCmdGet(const char* name) signde@220: { darkvater@289: _iconsole_cmd* item; signde@220: signde@220: item = _iconsole_cmds; signde@220: while (item != NULL) { darkvater@289: if (strcmp(item->name, name) == 0) return item; signde@220: item = item->_next; darkvater@289: } signde@220: return NULL; signde@220: } signde@220: darkvater@289: void IConsoleVarRegister(const char* name, void* addr, _iconsole_var_types type) signde@220: { darkvater@289: _iconsole_var* item; darkvater@289: _iconsole_var* item_new; signde@220: darkvater@289: item_new = malloc(sizeof(_iconsole_var)); /* XXX unchecked malloc */ signde@220: darkvater@289: item_new->name = malloc(strlen(name) + 2); /* XXX unchecked malloc */ darkvater@289: sprintf(item_new->name, "*%s", name); signde@220: signde@220: item_new->_next = NULL; darkvater@289: switch (type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: item_new->data.bool_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: darkvater@289: item_new->data.byte_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: item_new->data.uint16_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: item_new->data.uint32_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: item_new->data.int16_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: item_new->data.int32_ = addr; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_STRING: darkvater@289: item_new->data.string_ = addr; darkvater@289: break; darkvater@289: default: darkvater@301: error("unknown console variable type"); darkvater@289: break; darkvater@289: } darkvater@289: item_new->type = type; signde@220: item_new->_malloc = false; signde@220: signde@220: item_new->hook_access = NULL; signde@220: item_new->hook_after_change = NULL; signde@220: item_new->hook_before_change = NULL; signde@220: signde@220: item = _iconsole_vars; signde@220: if (item == NULL) { signde@220: _iconsole_vars = item_new; darkvater@289: } else { darkvater@289: while (item->_next != NULL) item = item->_next; signde@220: item->_next = item_new; darkvater@289: } signde@220: } signde@220: darkvater@289: void IConsoleVarMemRegister(const char* name, _iconsole_var_types type) signde@220: { darkvater@289: _iconsole_var* item; signde@220: item = IConsoleVarAlloc(type); darkvater@289: IConsoleVarInsert(item, name); signde@220: } signde@220: signde@220: darkvater@289: void IConsoleVarInsert(_iconsole_var* var, const char* name) signde@220: { darkvater@289: _iconsole_var* item; signde@220: darkvater@289: // disallow building variable rings darkvater@289: if (var->_next != NULL) return; signde@220: darkvater@289: var->name = malloc(strlen(name) + 2); /* XXX unchecked malloc */ darkvater@289: sprintf(var->name, "*%s", name); signde@220: signde@220: item = _iconsole_vars; signde@220: if (item == NULL) { darkvater@289: _iconsole_vars = var; darkvater@135: } else { darkvater@289: while (item->_next != NULL) item = item->_next; darkvater@289: item->_next = var; darkvater@135: } darkvater@135: } darkvater@135: darkvater@135: darkvater@289: _iconsole_var* IConsoleVarGet(const char* name) signde@220: { darkvater@289: _iconsole_var* item; darkvater@289: for (item = _iconsole_vars; item != NULL; item = item->_next) darkvater@289: if (strcmp(item->name, name) == 0) return item; signde@220: return NULL; darkvater@135: } darkvater@135: darkvater@289: _iconsole_var* IConsoleVarAlloc(_iconsole_var_types type) signde@220: { darkvater@289: _iconsole_var* item = malloc(sizeof(_iconsole_var)); /* XXX unchecked malloc */ signde@220: item->_next = NULL; darkvater@289: item->name = NULL; darkvater@289: item->type = type; signde@220: switch (item->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: item->data.bool_ = malloc(sizeof(*item->data.bool_)); darkvater@289: *item->data.bool_ = false; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: darkvater@289: item->data.byte_ = malloc(sizeof(*item->data.byte_)); darkvater@289: *item->data.byte_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: item->data.uint16_ = malloc(sizeof(*item->data.uint16_)); darkvater@289: *item->data.uint16_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: item->data.uint32_ = malloc(sizeof(*item->data.uint32_)); darkvater@289: *item->data.uint32_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: item->data.int16_ = malloc(sizeof(*item->data.int16_)); darkvater@289: *item->data.int16_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: item->data.int32_ = malloc(sizeof(*item->data.int32_)); darkvater@289: *item->data.int32_ = 0; darkvater@289: item->_malloc = true; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_POINTER: darkvater@301: case ICONSOLE_VAR_STRING: darkvater@301: // needs no memory ... it gets memory when it is set to an value darkvater@289: item->data.addr = NULL; darkvater@289: item->_malloc = false; darkvater@289: break; darkvater@289: default: darkvater@301: error("unknown console variable type"); darkvater@289: break; darkvater@289: } signde@220: signde@220: item->hook_access = NULL; signde@220: item->hook_after_change = NULL; signde@220: item->hook_before_change = NULL; signde@220: return item; darkvater@135: } darkvater@135: darkvater@135: darkvater@289: void IConsoleVarFree(_iconsole_var* var) signde@220: { darkvater@222: if (var->_malloc) darkvater@289: free(var->data.addr); darkvater@289: free(var->name); signde@220: free(var); darkvater@135: } darkvater@135: darkvater@289: void IConsoleVarSetString(_iconsole_var* var, const char* string) signde@220: { signde@220: if (string == NULL) return; signde@220: darkvater@289: if (var->_malloc) darkvater@289: free(var->data.string_); signde@220: darkvater@289: var->data.string_ = strdup(string); darkvater@289: var->_malloc = true; darkvater@222: } signde@220: darkvater@289: void IConsoleVarSetValue(_iconsole_var* var, int value) { signde@220: switch (var->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: *var->data.bool_ = (value != 0); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: darkvater@289: *var->data.byte_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: *var->data.uint16_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: *var->data.uint32_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: *var->data.int16_ = value; darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: *var->data.int32_ = value; darkvater@289: break; darkvater@289: default: darkvater@289: assert(0); darkvater@289: break; darkvater@222: } darkvater@135: } darkvater@135: darkvater@289: void IConsoleVarDump(const _iconsole_var* var, const char* dump_desc) signde@220: { darkvater@289: if (dump_desc == NULL) dump_desc = var->name; darkvater@135: darkvater@135: switch (var->type) { darkvater@135: case ICONSOLE_VAR_BOOLEAN: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %s", darkvater@289: dump_desc, *var->data.bool_ ? "true" : "false"); darkvater@289: break; darkvater@289: break; darkvater@135: case ICONSOLE_VAR_BYTE: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %u", darkvater@289: dump_desc, *var->data.byte_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_UINT16: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %u", darkvater@289: dump_desc, *var->data.uint16_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_UINT32: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %u", darkvater@289: dump_desc, *var->data.uint32_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_INT16: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %i", darkvater@289: dump_desc, *var->data.int16_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_INT32: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %i", darkvater@289: dump_desc, *var->data.int32_); darkvater@289: break; darkvater@135: case ICONSOLE_VAR_STRING: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = %s", darkvater@289: dump_desc, var->data.string_); darkvater@289: break; darkvater@141: case ICONSOLE_VAR_REFERENCE: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = @%s", darkvater@289: dump_desc, var->data.reference_); darkvater@135: case ICONSOLE_VAR_UNKNOWN: darkvater@135: case ICONSOLE_VAR_POINTER: darkvater@289: IConsolePrintF(_iconsole_color_default, "%s = @%p", darkvater@289: dump_desc, var->data.addr); darkvater@289: break; darkvater@301: case ICONSOLE_VAR_NONE: darkvater@301: IConsolePrintF(_iconsole_color_default, "%s = [nothing]", darkvater@301: dump_desc); darkvater@289: break; darkvater@289: } darkvater@135: } darkvater@135: signde@220: // * ************************* * // signde@220: // * hooking code * // signde@220: // * ************************* * // darkvater@135: darkvater@289: void IConsoleVarHook(const char* name, _iconsole_hook_types type, iconsole_var_hook proc) signde@220: { darkvater@289: _iconsole_var* hook_var = IConsoleVarGet(name); signde@220: if (hook_var == NULL) return; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: hook_var->hook_before_change = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: hook_var->hook_after_change = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: hook_var->hook_access = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: assert(0); darkvater@289: break; signde@220: } signde@220: } darkvater@135: darkvater@289: bool IConsoleVarHookHandle(_iconsole_var* hook_var, _iconsole_hook_types type) signde@220: { darkvater@289: iconsole_var_hook proc = NULL; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: proc = hook_var->hook_before_change; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: proc = hook_var->hook_after_change; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: proc = hook_var->hook_access; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: assert(0); darkvater@289: break; signde@220: } darkvater@289: return proc == NULL ? true : proc(hook_var); signde@220: } signde@220: darkvater@289: void IConsoleCmdHook(const char* name, _iconsole_hook_types type, iconsole_cmd_hook proc) signde@220: { darkvater@289: _iconsole_cmd* hook_cmd = IConsoleCmdGet(name); signde@220: if (hook_cmd == NULL) return; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: hook_cmd->hook_after_exec = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: hook_cmd->hook_before_exec = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: hook_cmd->hook_access = proc; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: assert(0); darkvater@289: break; signde@220: } signde@220: } signde@220: darkvater@289: bool IConsoleCmdHookHandle(_iconsole_cmd* hook_cmd, _iconsole_hook_types type) signde@220: { darkvater@289: iconsole_cmd_hook proc = NULL; signde@220: switch (type) { darkvater@289: case ICONSOLE_HOOK_AFTER_EXEC: darkvater@289: proc = hook_cmd->hook_after_exec; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_EXEC: darkvater@289: proc = hook_cmd->hook_before_exec; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_ACCESS: darkvater@289: proc = hook_cmd->hook_access; darkvater@289: break; darkvater@289: case ICONSOLE_HOOK_BEFORE_CHANGE: darkvater@289: case ICONSOLE_HOOK_AFTER_CHANGE: darkvater@289: assert(0); darkvater@289: break; signde@220: } darkvater@289: return proc == NULL ? true : proc(hook_cmd); signde@220: } signde@220: darkvater@289: void IConsoleCmdExec(const char* cmdstr) signde@220: { darkvater@289: _iconsole_cmd_addr function; darkvater@289: char* tokens[20]; darkvater@289: byte tokentypes[20]; darkvater@289: char* tokenstream; darkvater@289: char* tokenstream_s; darkvater@289: byte execution_mode; darkvater@289: _iconsole_var* var = NULL; darkvater@289: _iconsole_var* result = NULL; darkvater@289: _iconsole_cmd* cmd = NULL; signde@220: signde@220: bool longtoken; signde@220: bool valid_token; signde@220: bool skip_lt_change; signde@220: signde@220: int c; signde@220: int i; signde@220: int l; signde@220: signde@220: //** clearing buffer **// signde@220: darkvater@289: for (i = 0; i < 20; i++) { darkvater@289: tokens[i] = NULL; darkvater@289: tokentypes[i] = ICONSOLE_VAR_NONE; darkvater@289: } darkvater@289: tokenstream_s = tokenstream = malloc(1024); darkvater@289: memset(tokenstream, 0, 1024); signde@220: signde@220: //** parsing **// signde@220: darkvater@289: longtoken = false; darkvater@289: valid_token = false; darkvater@289: skip_lt_change = false; darkvater@289: l = strlen(cmdstr); darkvater@289: i = 0; darkvater@289: c = 0; signde@220: tokens[c] = tokenstream; darkvater@301: while (i < l && c < lengthof(tokens) - 1) { darkvater@289: if (cmdstr[i] == '"') { signde@220: if (longtoken) { darkvater@289: if (cmdstr[i + 1] == '"') { signde@220: i++; signde@220: *tokenstream = '"'; signde@220: tokenstream++; darkvater@289: skip_lt_change = true; darkvater@135: } else { darkvater@289: longtoken = !longtoken; darkvater@135: } darkvater@289: } else darkvater@289: longtoken = !longtoken; signde@220: if (!skip_lt_change) { signde@220: if (!longtoken) { signde@220: if (valid_token) { signde@220: c++; darkvater@289: *tokenstream = '\0'; signde@220: tokenstream++; signde@220: tokens[c] = tokenstream; signde@220: valid_token = false; signde@220: } darkvater@289: } signde@220: skip_lt_change=false; darkvater@135: } darkvater@289: } else if (!longtoken && cmdstr[i] == ' ') { signde@220: if (valid_token) { signde@220: c++; darkvater@289: *tokenstream = '\0'; signde@220: tokenstream++; signde@220: tokens[c] = tokenstream; signde@220: valid_token = false; signde@220: } darkvater@289: } else { darkvater@289: valid_token = true; signde@220: *tokenstream = cmdstr[i]; signde@220: tokenstream++; darkvater@289: } signde@220: i++; darkvater@289: } signde@220: signde@220: tokenstream--; darkvater@289: if (*tokenstream != '\0') { signde@220: c++; signde@220: tokenstream++; darkvater@289: *tokenstream = '\0'; darkvater@289: } signde@220: signde@220: //** interpreting **// signde@220: darkvater@289: for (i = 0; i < c; i++) { darkvater@289: tokentypes[i] = ICONSOLE_VAR_UNKNOWN; darkvater@289: if (tokens[i] != NULL && i > 0 && strlen(tokens[i]) > 0) { darkvater@289: if (tokens[i][0] == '*') { darkvater@301: // change the variable to an pointer if execution_mode != 4 is darkvater@301: // being prepared. execution_mode 4 is used to assign darkvater@301: // one variables data to another one darkvater@301: // [token 0 and 2] darkvater@301: if (!((i == 2) && (tokentypes[1] == ICONSOLE_VAR_UNKNOWN) && darkvater@301: (strcmp(tokens[1], "<<") == 0))) { signde@220: var = IConsoleVarGet(tokens[i]); darkvater@289: if (var != NULL) { darkvater@301: // pointer to the data --> token darkvater@301: tokens[i] = (char *) var->data.addr; /* XXX: maybe someone finds an cleaner way to do this */ darkvater@289: tokentypes[i] = var->type; darkvater@141: } darkvater@135: } darkvater@135: } darkvater@289: if (tokens[i] != NULL && tokens[i][0] == '@' && tokens[i][1] == '*') { darkvater@289: var = IConsoleVarGet(tokens[i] + 1); darkvater@289: if (var != NULL) { darkvater@301: // pointer to the _iconsole_var struct --> token darkvater@301: tokens[i] = (char *) var; /* XXX: maybe someone finds an cleaner way to do this */ darkvater@289: tokentypes[i] = ICONSOLE_VAR_REFERENCE; darkvater@289: } darkvater@289: } darkvater@135: } darkvater@289: } darkvater@135: signde@220: execution_mode=0; signde@220: signde@220: function = NULL; signde@220: cmd = IConsoleCmdGet(tokens[0]); signde@220: if (cmd != NULL) function = cmd->addr; signde@220: signde@220: if (function != NULL) { darkvater@289: execution_mode = 1; // this is a command darkvater@289: } else { signde@220: var = IConsoleVarGet(tokens[0]); signde@220: if (var != NULL) { darkvater@289: execution_mode = 2; // this is a variable darkvater@289: if (c > 2 && strcmp(tokens[1], "<<") == 0) { signde@220: // this is command to variable mode [normal] darkvater@222: signde@220: function = NULL; signde@220: cmd = IConsoleCmdGet(tokens[2]); signde@220: if (cmd != NULL) function = cmd->addr; signde@220: signde@220: if (function != NULL) { darkvater@289: execution_mode = 3; darkvater@289: } else { signde@220: result = IConsoleVarGet(tokens[2]); darkvater@289: if (result != NULL) signde@220: execution_mode=4; darkvater@135: } signde@220: } signde@220: } darkvater@289: } signde@220: signde@220: //** executing **// darkvater@289: if (_stdlib_con_developer) darkvater@289: IConsolePrintF(_iconsole_color_debug, "CONDEBUG: execution_mode: %i", darkvater@289: execution_mode); signde@220: switch (execution_mode) { darkvater@289: case 0: darkvater@289: // not found darkvater@289: IConsoleError("command or variable not found"); darkvater@289: break; darkvater@289: case 1: darkvater@289: if (IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_ACCESS)) { darkvater@289: // execution with command syntax darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_BEFORE_EXEC); darkvater@289: result = function(c, tokens, tokentypes); darkvater@289: if (result != NULL) { darkvater@289: IConsoleVarDump(result, "result"); darkvater@289: IConsoleVarFree(result); darkvater@289: } darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_AFTER_EXEC); darkvater@289: break; signde@220: } darkvater@289: case 2: signde@220: { darkvater@289: // execution with variable syntax darkvater@289: if (IConsoleVarHookHandle(var, ICONSOLE_HOOK_ACCESS) && (c == 2 || c == 3)) { darkvater@289: // ** variable modifications ** // darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_BEFORE_CHANGE); darkvater@289: switch (var->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: signde@220: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) { darkvater@289: *var->data.bool_ = (atoi(tokens[2]) != 0); signde@220: } else { darkvater@289: *var->data.bool_ = false; signde@220: } darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@301: *var->data.bool_ = true; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@301: *var->data.bool_ = false; darkvater@289: IConsoleVarDump(var, NULL); signde@220: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; signde@220: } darkvater@289: case ICONSOLE_VAR_BYTE: signde@220: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.byte_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.byte_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.byte_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--")==0) { darkvater@289: --*var->data.byte_; darkvater@289: IConsoleVarDump(var, NULL); signde@220: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.uint16_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.uint16_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.uint16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.uint16_; darkvater@289: IConsoleVarDump(var, NULL); signde@220: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; signde@220: } darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.uint32_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.uint32_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.uint32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.uint32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.int16_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.int16_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.int16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.int16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: *var->data.int32_ = atoi(tokens[2]); darkvater@289: else darkvater@289: *var->data.int32_ = 0; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@289: ++*var->data.int32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@289: --*var->data.int32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else { IConsoleError("operation not supported"); } darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_STRING: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) darkvater@289: IConsoleVarSetString(var, tokens[2]); darkvater@289: else darkvater@289: IConsoleVarSetString(var, ""); darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@289: case ICONSOLE_VAR_POINTER: darkvater@289: { darkvater@289: if (strcmp(tokens[1], "=") == 0) { darkvater@289: if (c == 3) { darkvater@289: if (tokentypes[2] == ICONSOLE_VAR_UNKNOWN) darkvater@301: var->data.addr = (void*)atoi(tokens[2]); /* direct access on memory [by address] */ darkvater@289: else darkvater@301: var->data.addr = (void*)tokens[2]; /* direct acces on memory [by variable] */ darkvater@289: } else darkvater@289: var->data.addr = NULL; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "++") == 0) { darkvater@301: ++*(char*)&var->data.addr; /* change the address + 1 */ darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } else if (strcmp(tokens[1], "--") == 0) { darkvater@301: --*(char*)&var->data.addr; /* change the address - 1 */ darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: } darkvater@289: else darkvater@289: IConsoleError("operation not supported"); darkvater@289: break; darkvater@289: } darkvater@301: case ICONSOLE_VAR_NONE: darkvater@301: case ICONSOLE_VAR_REFERENCE: darkvater@301: case ICONSOLE_VAR_UNKNOWN: darkvater@301: IConsoleError("operation not supported"); darkvater@289: break; signde@220: } darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_AFTER_CHANGE); darkvater@289: } darkvater@289: if (c == 1) // ** variable output ** // darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; signde@220: } darkvater@289: case 3: darkvater@289: case 4: signde@220: { darkvater@289: // execute command with result or assign a variable darkvater@289: if (execution_mode == 3) { darkvater@289: if (IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_ACCESS)) { darkvater@222: int i; darkvater@222: int diff; darkvater@289: void* temp; darkvater@222: byte temp2; signde@220: darkvater@222: // tokenshifting darkvater@289: for (diff = 0; diff < 2; diff++) { darkvater@289: temp = tokens[0]; darkvater@289: temp2 = tokentypes[0]; darkvater@289: for (i = 0; i < 19; i++) { darkvater@289: tokens[i] = tokens[i + 1]; darkvater@289: tokentypes[i] = tokentypes[i + 1]; darkvater@222: } darkvater@289: tokens[19] = temp; darkvater@289: tokentypes[19] = temp2; signde@220: } darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_BEFORE_EXEC); darkvater@289: result = function(c, tokens, tokentypes); darkvater@289: IConsoleCmdHookHandle(cmd, ICONSOLE_HOOK_AFTER_EXEC); darkvater@222: } else darkvater@289: execution_mode = 255; signde@220: } signde@220: darkvater@289: if (IConsoleVarHookHandle(var, ICONSOLE_HOOK_ACCESS) && result != NULL) { darkvater@289: if (result->type != var->type) { darkvater@289: IConsoleError("variable type missmatch"); signde@220: } else { darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_BEFORE_CHANGE); darkvater@289: switch (result->type) { darkvater@289: case ICONSOLE_VAR_BOOLEAN: darkvater@289: *var->data.bool_ = *result->data.bool_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_BYTE: darkvater@289: *var->data.byte_ = *result->data.byte_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT16: darkvater@289: *var->data.uint16_ = *result->data.uint16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_UINT32: darkvater@289: *var->data.uint32_ = *result->data.uint32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT16: darkvater@289: *var->data.int16_ = *result->data.int16_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_INT32: darkvater@289: *var->data.int32_ = *result->data.int32_; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_POINTER: darkvater@289: var->data.addr = result->data.addr; darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: case ICONSOLE_VAR_STRING: darkvater@289: IConsoleVarSetString(var, result->data.string_); darkvater@289: IConsoleVarDump(var, NULL); darkvater@289: break; darkvater@289: default: darkvater@289: IConsoleError("variable type missmatch"); darkvater@289: break; signde@220: } darkvater@289: IConsoleVarHookHandle(var, ICONSOLE_HOOK_AFTER_CHANGE); darkvater@135: } signde@220: darkvater@289: if (execution_mode == 3) { darkvater@289: IConsoleVarFree(result); darkvater@135: } darkvater@135: } darkvater@289: break; darkvater@135: } darkvater@289: default: darkvater@289: // execution mode invalid darkvater@289: IConsoleError("invalid execution mode"); darkvater@289: break; darkvater@135: } darkvater@135: darkvater@301: //** freeing the tokenstream **// signde@220: free(tokenstream_s); darkvater@135: }