From 4f5d3906eeb9b8e43e514b4c573076c33a080788 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Sun, 6 Apr 2008 05:41:17 +0000 Subject: [PATCH] history cleanups git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1734 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/console.cpp | 251 +++++++++++++++++++++++++---------------- source/src/console.h | 3 +- source/src/protos.h | 2 + 3 files changed, 160 insertions(+), 96 deletions(-) diff --git a/source/src/console.cpp b/source/src/console.cpp index a9e27a7a..a7582477 100644 --- a/source/src/console.cpp +++ b/source/src/console.cpp @@ -53,6 +53,7 @@ struct console : consolebuffer console con; textinputbuffer cmdline; +char *cmdaction = NULL, *cmdprompt = NULL; bool saycommandon = false; void setconskip(int n) { con.setconskip(n); } @@ -172,13 +173,22 @@ void saycommand(char *init) // turns input to the comman setscope(false); if(!editmode) keyrepeat(saycommandon); s_strcpy(cmdline.buf, init ? init : ""); + DELETEA(cmdaction); + DELETEA(cmdprompt); cmdline.pos = -1; - player1->stopmoving(); // prevent situations where player presses direction key, open command line, then releases key +} + +void inputcommand(char *init, char *action, char *prompt) +{ + saycommand(init); + if(action[0]) cmdaction = newstring(action); + if(prompt[0]) cmdprompt = newstring(prompt); } void mapmsg(char *s) { s_strncpy(hdr.maptitle, s, 128); } COMMAND(saycommand, ARG_VARI); +COMMAND(inputcommand, ARG_3STR); COMMAND(mapmsg, ARG_1STR); #if !defined(WIN32) && !defined(__APPLE__) @@ -223,113 +233,164 @@ void pasteconsole(char *dst) #endif } -cvector vhistory; +struct hline +{ + char *buf, *action, *prompt; + + hline() : buf(NULL), action(NULL), prompt(NULL) {} + ~hline() + { + DELETEA(buf); + DELETEA(action); + DELETEA(prompt); + } + + void restore() + { + s_strcpy(cmdline.buf, buf); + if(cmdline.pos >= (int)strlen(cmdline.buf)) cmdline.pos = -1; + DELETEA(cmdaction); + DELETEA(cmdprompt); + if(action) cmdaction = newstring(action); + if(prompt) cmdprompt = newstring(prompt); + } + + bool shouldsave() + { + return strcmp(cmdline.buf, buf) || + (cmdaction ? !action || strcmp(cmdaction, action) : action!=NULL) || + (cmdprompt ? !prompt || strcmp(cmdprompt, prompt) : prompt!=NULL); + } + + void save() + { + buf = newstring(cmdline.buf); + if(cmdaction) action = newstring(cmdaction); + if(cmdprompt) prompt = newstring(cmdprompt); + } + + void run() + { + if(action) + { + alias("cmdbuf", buf); + execute(action); + } + else if(buf[0]=='/') execute(buf+1); + else toserver(buf); + } +}; +vector history; int histpos = 0; -void history(int n) +void history_(int n) { - static bool inhistory = false; - if(!inhistory && vhistory.inrange(n)) + static bool inhistory = true; + if(!inhistory && history.inrange(n)) { inhistory = true; - char *buf = vhistory[vhistory.length()-n-1]; - if(buf[0]=='/') execute(buf+1); - else toserver(buf); + history[history.length()-n-1]->run(); inhistory = false; } } -COMMAND(history, ARG_1INT); +COMMANDN(history, history_, ARG_1INT); + +void execbind(keym &k, bool isdown) +{ + loopv(releaseactions) + { + releaseaction &ra = releaseactions[i]; + if(ra.key==&k) + { + if(!isdown) execute(ra.action); + delete[] ra.action; + releaseactions.remove(i--); + } + } + if(isdown) + { + keyaction = k.action; + keypressed = &k; + execute(keyaction); + keypressed = NULL; + if(keyaction!=k.action) delete[] keyaction; + } + k.pressed = isdown; +} + +void consolekey(int code, bool isdown, int cooked) +{ + if(isdown) + { + switch(code) + { + case SDLK_F1: + toggledoc(); + break; + + case SDLK_F2: + scrolldoc(-4); + break; + + case SDLK_F3: + scrolldoc(4); + break; + + case SDLK_UP: + if(histpos>0) history[--histpos]->restore(); + break; + + case SDLK_DOWN: + if(histpos+1restore(); + break; + + case SDLK_TAB: + if(!cmdaction) + { + complete(cmdline.buf); + if(cmdline.pos>=0 && cmdline.pos>=(int)strlen(cmdline.buf)) cmdline.pos = -1; + } + break; + + default: + resetcomplete(); + cmdline.key(code, isdown, cooked); + break; + } + } + else + { + if(code==SDLK_RETURN) + { + hline *h = NULL; + if(cmdline.buf[0]) + { + if(history.empty() || history.last()->shouldsave()) + history.add(h = new hline)->save(); // cap this? + else h = history.last(); + } + histpos = history.length(); + saycommand(NULL); + if(h) h->run(); + } + else if(code==SDLK_ESCAPE) + { + histpos = history.length(); + saycommand(NULL); + } + } +} void keypress(int code, bool isdown, int cooked) { - if(saycommandon) // keystrokes go to commandline + keym *haskey = NULL; + loopv(keyms) if(keyms[i].code==code) { haskey = &keyms[i]; break; } + if(haskey && haskey->pressed) execbind(*haskey, isdown); // allow pressed keys to release + else if(saycommandon) consolekey(code, isdown, cooked); // keystrokes go to commandline + else if(!menukey(code, isdown, cooked)) // keystrokes go to menu { - if(isdown) - { - switch(code) - { - case SDLK_F1: - toggledoc(); - break; - - case SDLK_F2: - scrolldoc(-4); - break; - - case SDLK_F3: - scrolldoc(4); - break; - - case SDLK_UP: - if(histpos>0) s_strcpy(cmdline.buf, vhistory[--histpos]); - break; - - case SDLK_DOWN: - if(histpos+1=0 && cmdline.pos>=(int)strlen(cmdline.buf)) cmdline.pos = -1; - break; - - default: - resetcomplete(); - cmdline.key(code, isdown, cooked); - break; - } - } - else - { - if(code==SDLK_RETURN) - { - string buf; // use a copy to safely close the commandline - s_strcpy(buf, cmdline.buf); - saycommand(NULL); - - if(buf[0]) - { - if(buf[0]=='/') execute(buf+1); - else toserver(buf); - - if(vhistory.empty() || strcmp(vhistory.last(), buf)) - vhistory.add(newstring(buf)); // cap this? - } - histpos = vhistory.length(); - } - else if(code==SDLK_ESCAPE) - { - histpos = vhistory.length(); - saycommand(NULL); - } - } - } - else if(!menukey(code, isdown, cooked)) // keystrokes go to menu - { - loopv(keyms) if(keyms[i].code==code) // keystrokes go to game, lookup in keymap and execute - { - keym &k = keyms[i]; - loopv(releaseactions) - { - releaseaction &ra = releaseactions[i]; - if(ra.key==&k) - { - if(!isdown) execute(ra.action); - delete[] ra.action; - releaseactions.remove(i--); - } - } - if(isdown) - { - keyaction = k.action; - keypressed = &k; - execute(keyaction); - keypressed = NULL; - if(keyaction!=k.action) delete[] keyaction; - } - break; - } + if(haskey) execbind(*haskey, isdown); } } diff --git a/source/src/console.h b/source/src/console.h index 5627cd33..a71059f1 100644 --- a/source/src/console.h +++ b/source/src/console.h @@ -89,7 +89,8 @@ struct textinputbuffer pasteconsole(buf); break; } - + // fall through + default: { if(unicode) diff --git a/source/src/protos.h b/source/src/protos.h index 41a6d414..a6af0903 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -60,7 +60,9 @@ struct keym { int code; char *name, *action; + bool pressed; + keym() : code(-1), name(NULL), action(NULL), pressed(false) {} ~keym() { DELETEA(name); DELETEA(action); } };