summaryrefslogtreecommitdiff
path: root/Dalos
diff options
context:
space:
mode:
authorpixel <pixel>2004-07-23 01:11:34 +0000
committerpixel <pixel>2004-07-23 01:11:34 +0000
commitaa678bc560d5ac65f694ba485caae6e09531364f (patch)
tree614cd7ef37a9b31a467094dd2d37b82eeab0373d /Dalos
parent6ea139d3259d0495d30a6a558876a431c77d3d30 (diff)
Basic LUA in Dalos
Diffstat (limited to 'Dalos')
-rw-r--r--Dalos/Dalos.cc441
1 files changed, 425 insertions, 16 deletions
diff --git a/Dalos/Dalos.cc b/Dalos/Dalos.cc
index c9d8763..07bcbcd 100644
--- a/Dalos/Dalos.cc
+++ b/Dalos/Dalos.cc
@@ -1,24 +1,418 @@
+/*
+ * Dalos
+ * Copyright (C) 2004 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: Dalos.cc,v 1.2 2004-07-23 01:11:34 pixel Exp $ */
+
#include <SDL.h>
+#include <SDL_thread.h>
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include <vector>
+
#include <Main.h>
+#include <Input.h>
+#include <Buffer.h>
+#include <BLua.h>
+#include <LuaHandle.h>
#include <engine.h>
#include <glbase.h>
#include <glshape.h>
+#include <font.h>
+
+#ifdef __MINGW32__
+#define main SDL_main
+#endif
+
+bool auto_exec = true;
+bool started = false;
+bool lua_break = false;
+
+String prompt = "> ";
+
+SDL_mutex * lua_command_lock;
+SDL_sem * lua_command_sem;
+Buffer lua_command;
+
+SDL_mutex * key_vect_mutex;
+SDL_sem * key_vect_size;
+std::vector<Uint16> key_vect;
+
+CODE_BEGINS
+class console;
+
+console * Console;
mogltk::widgets::Root * Root;
-mogltk::widgets::Frame * Frame;
+mogltk::widget * Frame;
mogltk::widgets::Menu * MainMenu;
-CODE_BEGINS
+
+static int lua_print(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ String t = L->tostring() + "\n";
+ char * tc = t.strdup();
+
+ printm(M_STATUS, "%s", tc);
+
+ free(tc);
+
+ return 0;
+}
+
+static void lua_hook(lua_State * _L, lua_Debug * ar) {
+ if (!started)
+ return;
+ Lua * L = Lua::find(_L);
+
+ if (lua_break) {
+ L->error("Breaking");
+ lua_break = false;
+ }
+}
+
+static int rl_getc_func(FILE * d) {
+ int k;
+ SDL_SemWait(key_vect_size);
+ SDL_mutexP(key_vect_mutex);
+ k = key_vect[0];
+ key_vect.erase(key_vect.begin());
+ SDL_mutexV(key_vect_mutex);
+ return k;
+}
+
+static void rl_redisplay_func(void) {
+ Application->Console->page_reset();
+}
+
+static void rl_prep_term_func(int b) {
+}
+
+static void rl_deprep_term_func(void) {
+}
+
+static int readline_thread(void * d) {
+ char * line_read;
+ String line, endline;
+ bool runit;
+ int pos;
+
+
+ rl_getc_function = rl_getc_func;
+ rl_redisplay_function = rl_redisplay_func;
+ rl_prep_term_function = rl_prep_term_func;
+ rl_deprep_term_function = rl_deprep_term_func;
+ rl_bind_key('\t', rl_insert);
+
+ while (true) {
+ line_read = readline("");
+ if (!line_read)
+ continue;
+ if (*line_read)
+ add_history(line_read);
+ Application->Console->add_line(prompt + line_read);
+
+ line = line_read;
+ line = line.trim();
+ endline = "";
+
+ /* Splitting the line between ;; */
+ while (line.strlen()) {
+ runit = false;
+
+ if ((pos = line.strstr(";;")) >= 0) {
+ endline = line.extract(pos + 2);
+ line = line.extract(0, pos);
+ runit = true;
+ } else {
+ endline = "";
+ }
+
+ if (line[line.strlen() - 1] == '\\') {
+ line[line.strlen() - 1] = ' ';
+ } else if (auto_exec) {
+ runit = true;
+ }
+ SDL_mutexP(lua_command_lock);
+ lua_command << line;
+ SDL_mutexV(lua_command_lock);
+
+ if (runit) {
+ SDL_SemPost(lua_command_sem);
+ prompt = "> ";
+ } else {
+ prompt = "- ";
+ }
+ line = endline.trim();
+ }
+
+ free(line_read);
+ }
+
+ return 0;
+}
+
+void start_lua() {
+ Lua * L = new Lua();
+
+ L->open_base();
+ L->open_math();
+ L->open_string();
+ L->open_table();
+
+ LuaInput::pushconstruct(L);
+ LuaOutput::pushconstruct(L);
+ LuaBuffer::pushconstruct(L);
+
+ // CD_PUSHSTATICS(L);
+ // Luapsx::pushstatics(L);
+
+ L->push("print");
+ L->push(lua_print);
+ L->setvar();
+
+ L->sethook(lua_hook, LUA_MASKLINE, 0);
+
+ lua_command_lock = SDL_CreateMutex();
+ lua_command_sem = SDL_CreateSemaphore(0);
+
+ SDL_CreateThread(LuaThread, L);
+}
+
+static int LuaThread(void * d) {
+ Lua * L = (Lua *) d;
+ while (true) {
+ SDL_SemWait(lua_command_sem);
+ started = true;
+ SDL_mutexP(lua_command_lock);
+ try {
+ L->load(&lua_command);
+ }
+ catch (LuaException e) {
+ /* If there was an error, ignore it, and free the stack */
+ while(L->gettop())
+ L->pop();
+ }
+ catch (GeneralException e) {
+ /* A more severe exception... */
+ while(L->gettop())
+ L->pop();
+ printm(M_ERROR, "Aborted. LUA caused the following exception: %s\n", e.GetMsg());
+ }
+ SDL_mutexV(lua_command_lock);
+ started = false;
+ }
+}
+
+class console_keyevent : public mogltk::engine::keyevent {
+ public:
+ virtual void down(SDL_keysym k) {
+ if (Application->Console->GetVisible()) {
+ SDL_mutexP(key_vect_mutex);
+ switch (k.sym) {
+ case SDLK_ESCAPE:
+ Application->Console->SetVisible(false);
+ SDL_mutexV(key_vect_mutex);
+ return;
+ case SDLK_DELETE:
+ key_vect.push_back('D' - '@');
+ break;
+ case SDLK_LEFT:
+ key_vect.push_back('B' - '@');
+ break;
+ case SDLK_RIGHT:
+ key_vect.push_back('F' - '@');
+ break;
+ case SDLK_UP:
+ key_vect.push_back('P' - '@');
+ break;
+ case SDLK_DOWN:
+ key_vect.push_back('N' - '@');
+ break;
+ case SDLK_HOME:
+ key_vect.push_back('A' - '@');
+ break;
+ case SDLK_END:
+ key_vect.push_back('E' - '@');
+ break;
+ case SDLK_PAGEUP:
+ Application->Console->page_up();
+ SDL_mutexV(key_vect_mutex);
+ return;
+ case SDLK_PAGEDOWN:
+ Application->Console->page_down();
+ SDL_mutexV(key_vect_mutex);
+ return;
+ case SDLK_c:
+ if (k.mod & KMOD_CTRL) {
+ if (started)
+ lua_break = true;
+ SDL_mutexV(key_vect_mutex);
+ return;
+ }
+ default:
+ if (k.unicode) {
+ key_vect.push_back(k.unicode);
+ } else {
+ SDL_mutexV(key_vect_mutex);
+ if (old_handler)
+ old_handler->down(k);
+ return;
+ }
+ }
+ SDL_mutexV(key_vect_mutex);
+ SDL_SemPost(key_vect_size);
+ } else {
+ if (k.sym == SDLK_ESCAPE) {
+ Application->Console->SetVisible(true);
+ return;
+ }
+ if (old_handler)
+ old_handler->down(k);
+ }
+ }
+ virtual void up(SDL_keysym k) {
+ if (old_handler)
+ old_handler->up(k);
+ }
+};
+
+class myprinter : public printer_t {
+ public:
+ myprinter() : lock(SDL_CreateMutex()) { }
+ virtual ~myprinter() { SDL_DestroyMutex(lock); }
+ virtual bool printm(int level, const char * m, va_list ap) {
+ static String heads[] = {"EE", "--", "WW", "II"};
+ static char buffer[20480];
+
+ if (level >= M_INFO)
+ return true;
+
+ SDL_mutexP(lock);
+
+ vsprintf(buffer, m, ap);
+ if (level >= 0)
+ Application->Console->add_line("(" + heads[level] + ") " + buffer);
+ else
+ Application->Console->add_line(buffer);
+
+ SDL_mutexV(lock);
+
+ return true;
+ }
+ private:
+ SDL_mutex * lock;
+};
+
+class console : public mogltk::widget {
+ public:
+ console(mogltk::shape * sh, mogltk::widget * father, int y, int _nlines) :
+ widget(father, 0, y, father->GetW(), _nlines * 13, 0, "console", sh), nlines(_nlines), page(0), protect_add_line(SDL_CreateMutex()) { SetVisible(false); }
+ virtual ~console() { SDL_DestroyMutex(protect_add_line); }
+ void add_line(const String & s) {
+ SDL_mutexP(protect_add_line);
+ lines.insert(lines.begin(), 1, s);
+ while (lines.size() >= 1024) {
+ lines.pop_back();
+ }
+ SDL_mutexV(protect_add_line);
+ }
+ void page_reset() {
+ page = 0;
+ }
+ void page_up() {
+ page += nlines;
+ if (page > (lines.size() - nlines))
+ page = lines.size() - nlines;
+ }
+ void page_down() {
+ page -= nlines;
+ if (page < 0)
+ page = 0;
+ }
+ protected:
+ virtual void draw() {
+ int cursor_pos, start, line_length, line_pos, cur_page;
+
+ mogltk::ColorP::Max.A = 120;
+ std::vector<String>::iterator i;
+
+ // Background
+ Shaper()->box(GetAX(), GetAY(), GetAX2(), GetAY2(), BLUE);
+ Shaper()->obox(GetAX(), GetAY(), GetAX2(), GetAY2(), BLUE);
+
+ mogltk::ColorP::Max.A = 255;
+ mogltk::FixedFont->setcolor(WHITE);
+
+ // Lines
+ SDL_mutexP(protect_add_line);
+ i = lines.begin();
+ for (cur_page = page; cur_page && (i != lines.end()); cur_page--, i++);
+
+ for (line_pos = nlines - 2; (line_pos >= 0) && (i != lines.end()); line_pos--, i++) {
+ const char * line;
+ mogltk::FixedFont->putcursor(GetAX(), GetAY() + line_pos * 13);
+ line = i->to_charp();
+ mogltk::FixedFont->printf("%s", line);
+ }
+ SDL_mutexV(protect_add_line);
+
+ // Cursor
+ cursor_pos = rl_point;
+ start = 0;
+
+ line_length = strlen(rl_line_buffer);
+
+// while ((((cursor_pos + 2) * 6) >= GetW() || (((line_length - start + 2) * 6) >= GetW())) && (cursor_pos >= 16)) {
+ while (((cursor_pos + 2) * 6) >= GetW()) {
+ cursor_pos -= 16;
+ start += 16;
+ }
+
+ mogltk::ColorP::Max.A = 200;
+ Shaper()->box(GetAX() + 6 * (cursor_pos + 2), GetAY() + (nlines - 1) * 13, GetAX() + 6 * (cursor_pos + 3) - 1, GetAY() + nlines * 13, GREEN);
+
+ mogltk::ColorP::Max.A = 255;
+ mogltk::FixedFont->putcursor(GetAX(), GetAY() + (nlines - 1) * 13);
+ mogltk::FixedFont->printf(prompt);
+ mogltk::FixedFont->printf("%s", rl_line_buffer + start);
+ }
+ virtual bool process_event(int mx, int my, mogltk::event_t event) {
+ }
+ private:
+ int nlines, page;
+ std::vector<String> lines;
+ SDL_mutex * protect_add_line;
+};
class frame : public mogltk::widget {
public:
frame(mogltk::shape * sh, mogltk::widget * father) :
widget(father, 2, 2, father->GetW() - 4, father->GetH() - 4, 0, "MyFrame", sh) { }
- protected:
+ protected:
virtual void draw() {
}
virtual bool process_event(int mx, int my, mogltk::event_t event) {
+ mx -= GetAX();
+ my -= GetAY();
return false;
}
};
@@ -26,7 +420,7 @@ class frame : public mogltk::widget {
class timer : public mogltk::widget {
public:
timer() :
- widget(Root, 0, 0, 0, 0, 0, "Timer", 0), tick(0)
+ widget(Application->Root, 0, 0, 0, 0, 0, "Timer", 0), tick(0)
{ set_timed_event(100); }
protected:
virtual bool process_event(int, int, mogltk::event_t event) {
@@ -35,18 +429,19 @@ class timer : public mogltk::widget {
tick = (tick + 1) % 4;
switch (tick) {
case 0:
- MainMenu->SetCaption(0, "/");
+ Application->MainMenu->SetCaption(0, "/");
break;
case 1:
- MainMenu->SetCaption(0, "-");
+ Application->MainMenu->SetCaption(0, "-");
break;
case 2:
- MainMenu->SetCaption(0, "\\");
+ Application->MainMenu->SetCaption(0, "\\");
break;
case 3:
- MainMenu->SetCaption(0, "I");
+ Application->MainMenu->SetCaption(0, "I");
break;
}
+ Application->MainMenu->SetCaption(3, String("FPS: ") + mogltk::engine::FPS());
return true;
}
return false;
@@ -79,35 +474,49 @@ class about : public mogltk::widgets::action {
} about_dialog;
virtual int startup() throw (GeneralException) {
+ verbosity = M_INFO;
+ new Archive(argv[0], ARCHIVE_EXECUTABLE);
+
mogltk::widgets::ContextMenu * c;
mogltk::base * gl = new mogltk::glbase();
mogltk::shape * sh = new mogltk::glshape();
+ key_vect_mutex = SDL_CreateMutex();
+ key_vect_size = SDL_CreateSemaphore(0);
+
+ SDL_EnableKeyRepeat(250, 40);
+
mogltk::engine::setcursorvisible(true);
mogltk::engine::setappactive(true);
Root = new mogltk::widgets::Root(sh);
MainMenu = new mogltk::widgets::Menu(sh, Root);
- Frame = new mogltk::widgets::Frame(sh, Root, 0, MainMenu->GetH(), Root->GetW() - 1, Root->GetH() - MainMenu->GetH() - 1);
- new frame(sh, Frame);
+ Frame = new frame(sh, new mogltk::widgets::Frame(sh, Root, 0, MainMenu->GetH(), Root->GetW() - 1, Root->GetH() - MainMenu->GetH() - 1));
+ Console = new console(sh, Frame, 0, 8);
+ Console->move(0, Frame->GetH() - Console->GetH());
+ Console->add_line("Dalos v0.1 - LUA console");
+
+ start_lua();
+
+ printer = new myprinter();
+ SDL_CreateThread(readline_thread, 0);
MainMenu->addnode("/", 0);
c = MainMenu->createsub("File");
- c->addnode("Load", 0);
- c->addnode("Save", 0);
- c->addline();
c->addnode("Quit", &action_quit);
- c = MainMenu->createsub("Execution");
- c->addnode("Run", 0);
-
c = MainMenu->createsub("Help");
c->addnode("About", &about_dialog);
+
+ MainMenu->addnode("FPS:", 0);
new timer();
+ new console_keyevent;
Root->mainloop();
+
+ // Should cleanup here...
return 0;
}