@@ -54,22 +54,104 @@ typedef struct { char basename[64]; Filter filters[64]; Uint8 nfilters; } DependentPicture; + +typedef struct { + sqlite3_vtab_cursor super; + int pos; +} Cursor; static Uint8 cur_type; static Uint8 gsizes[16]; +static Picture*cur_pic; static void fn_valid_name(sqlite3_context*cxt,int argc,sqlite3_value**argv) { const char*s=sqlite3_value_text(*argv); if(!s || !*s || s[strspn(s,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-0123456789")]) { sqlite3_result_error(cxt,"Invalid name",-1); return; } sqlite3_result_value(cxt,*argv); } + +static int vt_graph_close(sqlite3_vtab_cursor*cur) { + sqlite3_free(cur); + return SQLITE_OK; +} + +static int vt_graph_eof(sqlite3_vtab_cursor*cc) { + Cursor*cur=(void*)cc; + return (!cur_pic || cur->pos>=cur_pic->size*cur_pic->size); +} + +static int vt_graph_open(sqlite3_vtab*vt,sqlite3_vtab_cursor**cur) { + *cur=sqlite3_malloc(sizeof(Cursor)); + return *cur?SQLITE_OK:SQLITE_NOMEM; +} + +static int vt_graph_connect(sqlite3*db,void*aux,int argc,const char*const*argv,sqlite3_vtab**vt,char**ex) { + *vt=sqlite3_malloc(sizeof(sqlite3_vtab)); + if(!*vt) return SQLITE_NOMEM; + sqlite3_declare_vtab(db,"CREATE TABLE `GRID`(`X` INT, `Y` INT, `C` INT);"); + return SQLITE_OK; +} + +static int vt_graph_disconnect(sqlite3_vtab*vt) { + sqlite3_free(vt); + return SQLITE_OK; +} + +static int vt_graph_filter(sqlite3_vtab_cursor*cc,int n,const char*s,int c,sqlite3_value**v) { + Cursor*cur=(void*)cc; + cur->pos=0; + return SQLITE_OK; +} + +static int vt_graph_index(sqlite3_vtab*vt,sqlite3_index_info*inf) { + return SQLITE_OK; +} + +static int vt_graph_column(sqlite3_vtab_cursor*cc,sqlite3_context*cxt,int n) { + Cursor*cur=(void*)cc; + sqlite3_result_int(cxt,n==0?cur->pos%cur_pic->size:n==1?cur->pos/cur_pic->size:cur_pic->data[cur->pos+cur_pic->size]); + return SQLITE_OK; +} + +static int vt_graph_next(sqlite3_vtab_cursor*cc) { + Cursor*cur=(void*)cc; + cur->pos++; + return SQLITE_OK; +} + +static int vt_graph_rowid(sqlite3_vtab_cursor*cc,sqlite3_int64*p) { + Cursor*cur=(void*)cc; + *p=cur->pos; + return SQLITE_OK; +} + +static int vt_graph_update(sqlite3_vtab*vt,int argc,sqlite3_value**argv,sqlite3_int64*rowid) { + if(argc!=5 || sqlite3_value_type(argv[0])==SQLITE_NULL) return SQLITE_ERROR; + cur_pic->data[cur_pic->size+sqlite3_value_int(argv[0])]=sqlite3_value_int(argv[4]); + return SQLITE_OK; +} + +static const sqlite3_module vt_graph={ + .iVersion=1, + .xBestIndex=vt_graph_index, + .xClose=vt_graph_close, + .xColumn=vt_graph_column, + .xConnect=vt_graph_connect, + .xDisconnect=vt_graph_disconnect, + .xEof=vt_graph_eof, + .xFilter=vt_graph_filter, + .xNext=vt_graph_next, + .xOpen=vt_graph_open, + .xRowid=vt_graph_rowid, + .xUpdate=vt_graph_update, +}; static int load_picture_file(void) { sqlite3_stmt*st=0; FILE*fp; char*nam; @@ -518,10 +600,15 @@ fputc(pal[c].b,fp); fputc(pal[c].b,fp); fputc(c?255:0,fp); fputc(c?255:0,fp); } pclose(fp); } + +static int response_cb(void*aux,int argc,char**argv,char**names) { + if(argc && *argv) screen_message(*argv); + return 1; +} static inline void edit_picture_1(Picture**pict,const char*name) { static const Uint8 shade[64]= "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" @@ -558,10 +645,11 @@ unsigned char buf[256]; m.x=m.y=m.w=m.h=0; set_cursor(XC_arrow); redraw: if((sel&~15) || !pict[sel]) sel=0; + cur_pic=pict[sel]; z=screen->w-pict[sel]->size-169; if(z>screen->h-49) z=screen->h-49; z/=pict[sel]->size; if(z<3) return; if(z>32) z=32; @@ -902,10 +990,14 @@ case SDLK_LEFT: case SDLK_KP4: --cc; goto redraw; case SDLK_RIGHT: case SDLK_KP6: ++cc; goto redraw; case SDLK_UP: case SDLK_KP8: cc-=16; goto redraw; case SDLK_DOWN: case SDLK_KP2: cc+=16; goto redraw; case SDLK_HOME: case SDLK_KP7: cc=0; goto redraw; + case SDLK_F12: + p=(Uint8*)screen_prompt(""); + if(p) sqlite3_exec(userdb,p,response_cb,0,0); + goto redraw; } break; case SDL_VIDEOEXPOSE: goto redraw; } @@ -1303,10 +1395,11 @@ pict[i]->size=gsizes[i]; memset(pict[i]->data,0,(gsizes[i]+1)*gsizes[i]); } } edit_picture_1(pict,name); + cur_pic=0; fp=open_memstream((char**)&buf,&size); if(!fp) fatal("Cannot open memory stream\n"); for(i=n=0;i<16;i++) if(pict[i]) n++; fputc(n,fp); for(i=0;isize,fp); @@ -1440,10 +1533,11 @@ sqlite3_stmt*st; int sc=0; int max=load_picture_file(); int i,n; sqlite3_create_function(userdb,"VALID_NAME",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_valid_name,0,0); + sqlite3_create_module(userdb,"GRAPH",&vt_graph,0); init_palette(); optionquery[1]=Q_imageSize; *gsizes=picture_size=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"16",0,10); set_cursor(XC_arrow); set_caption();