Overview
Comment: | Implement the "CLASSES" virtual table and the "CLASS_DATA" SQL function. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
829b9ff683bf46c737539fa5ae3adaa5 |
User & Date: | user on 2018-07-14 00:19:53 |
Other Links: | manifest | tags |
Context
2018-07-14
| ||
00:23 | Ensure each line of help text ends with a line break check-in: c1a1e6bede user: user tags: trunk | |
00:19 | Implement the "CLASSES" virtual table and the "CLASS_DATA" SQL function. check-in: 829b9ff683 user: user tags: trunk | |
2018-07-10
| ||
05:56 | Add a "maxObjects" resource. Also add some missing "extern" from declarations in heromesh.h and add a hidden "heap test" option check-in: 402432f1b2 user: user tags: trunk | |
Changes
Modified function.c from [aa26680e3f] to [dee2ab208b].
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include "heromesh.h" typedef struct { struct sqlite3_vtab_cursor; sqlite3_int64 rowid; char unique,eof; } Cursor; static void fn_basename(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_text(cxt,basefilename,-1,SQLITE_STATIC); } static void fn_cacheid(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_int64(cxt,*(sqlite3_int64*)sqlite3_user_data(cxt)); } static void fn_modstate(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_int(cxt,SDL_GetModState()); } static void fn_picture_size(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_int(cxt,picture_size); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #include "heromesh.h" typedef struct { struct sqlite3_vtab_cursor; sqlite3_int64 rowid; char unique,eof; } Cursor; static void find_first_usable_image(const Class*cl,sqlite3_context*cxt) { int i; if(cl->cflags&CF_GROUP) return; if(!cl->images) return; for(i=0;i<cl->nimages;i++) { if(cl->images[i]&0x8000) { sqlite3_result_int(cxt,i); return; } } } static void fn_basename(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_text(cxt,basefilename,-1,SQLITE_STATIC); } static void fn_cacheid(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_int64(cxt,*(sqlite3_int64*)sqlite3_user_data(cxt)); } static void fn_class_data(sqlite3_context*cxt,int argc,sqlite3_value**argv) { int id=sqlite3_value_int(argv[0]); Class*cl; if(id<0 || id>=0x4000 || !classes[id]) return; cl=classes[id]; switch(sqlite3_value_int(argv[1])&255) { case 0: sqlite3_result_int(cxt,id); break; case 1: sqlite3_result_int64(cxt,cl->temperature); break; case 2: sqlite3_result_int(cxt,cl->shape); break; case 7: find_first_usable_image(cl,cxt); break; case 12: sqlite3_result_int64(cxt,cl->misc4&0xFFFFFFFFULL); break; case 13: sqlite3_result_int64(cxt,cl->misc5&0xFFFFFFFFULL); break; case 14: sqlite3_result_int64(cxt,cl->misc6&0xFFFFFFFFULL); break; case 15: sqlite3_result_int64(cxt,cl->misc7&0xFFFFFFFFULL); break; case 18: sqlite3_result_int64(cxt,cl->arrivals); break; case 19: sqlite3_result_int64(cxt,cl->departures); break; case 32: sqlite3_result_int(cxt,cl->oflags&OF_BUSY?1:0); break; case 33: sqlite3_result_int(cxt,cl->oflags&OF_INVISIBLE?1:0); break; case 34: sqlite3_result_int(cxt,cl->oflags&OF_USERSIGNAL?1:0); break; case 35: sqlite3_result_int(cxt,cl->oflags&OF_USERSTATE?1:0); break; case 36: sqlite3_result_int(cxt,cl->oflags&OF_KEYCLEARED?1:0); break; case 37: sqlite3_result_int(cxt,cl->cflags&CF_PLAYER?1:0); break; case 38: sqlite3_result_int(cxt,cl->oflags&OF_DESTROYED?1:0); break; case 39: sqlite3_result_int(cxt,cl->oflags&OF_STEALTHY?1:0); break; case 40: sqlite3_result_int(cxt,cl->oflags&OF_VISUALONLY?1:0); break; case 64: sqlite3_result_int64(cxt,cl->density); break; case 65: sqlite3_result_int64(cxt,cl->volume); break; case 66: sqlite3_result_int64(cxt,cl->strength); break; case 67: sqlite3_result_int64(cxt,cl->weight); break; case 69: sqlite3_result_int64(cxt,cl->height); break; case 70: sqlite3_result_int64(cxt,cl->climb); break; case 72: sqlite3_result_int(cxt,cl->hard[0]); break; case 73: sqlite3_result_int(cxt,cl->hard[1]); break; case 74: sqlite3_result_int(cxt,cl->hard[2]); break; case 75: sqlite3_result_int(cxt,cl->hard[3]); break; case 76: sqlite3_result_int(cxt,cl->sharp[0]); break; case 77: sqlite3_result_int(cxt,cl->sharp[1]); break; case 78: sqlite3_result_int(cxt,cl->sharp[2]); break; case 79: sqlite3_result_int(cxt,cl->sharp[3]); break; case 80: sqlite3_result_int(cxt,(cl->shape>>0)&3); break; case 81: sqlite3_result_int(cxt,(cl->shape>>2)&3); break; case 82: sqlite3_result_int(cxt,(cl->shape>>4)&3); break; case 83: sqlite3_result_int(cxt,(cl->shape>>6)&3); break; case 84: sqlite3_result_int(cxt,cl->shovable); break; case 128: sqlite3_result_double(cxt,cl->volume/(double)max_volume); break; case 129: sqlite3_result_int(cxt,cl->uservars); break; case 130: sqlite3_result_int(cxt,cl->collisionLayers); break; case 132: sqlite3_result_int(cxt,cl->cflags&CF_COMPATIBLE?1:0); break; } } static void fn_modstate(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_int(cxt,SDL_GetModState()); } static void fn_picture_size(sqlite3_context*cxt,int argc,sqlite3_value**argv) { sqlite3_result_int(cxt,picture_size); |
︙ | ︙ | |||
88 89 90 91 92 93 94 | static int vt0_eof(sqlite3_vtab_cursor*pcur) { Cursor*cur=(void*)pcur; return cur->eof; } static int vt0_index(sqlite3_vtab*vt,sqlite3_index_info*info) { int i; | | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | static int vt0_eof(sqlite3_vtab_cursor*pcur) { Cursor*cur=(void*)pcur; return cur->eof; } static int vt0_index(sqlite3_vtab*vt,sqlite3_index_info*info) { int i; if(info->nOrderBy==1 && (info->aOrderBy->iColumn==-1 || !info->aOrderBy->iColumn) && !info->aOrderBy->desc) info->orderByConsumed=1; for(i=0;i<info->nConstraint;i++) { if((info->aConstraint[i].iColumn==-1 || !info->aConstraint[i].iColumn) && info->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ && info->aConstraint[i].usable) { info->aConstraintUsage[i].argvIndex=1; info->aConstraintUsage[i].omit=1; info->idxFlags=SQLITE_INDEX_SCAN_UNIQUE; break; } } return SQLITE_OK; |
︙ | ︙ | |||
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | Module(vt_messages, .xColumn=vt1_messages_column, .xFilter=vt1_messages_filter, .xNext=vt1_messages_next, .xUpdate=vt1_messages_update, ); void init_sql_functions(sqlite3_int64*ptr0,sqlite3_int64*ptr1) { sqlite3_create_function(userdb,"BASENAME",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_basename,0,0); sqlite3_create_function(userdb,"LEVEL_CACHEID",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,ptr0,fn_cacheid,0,0); sqlite3_create_function(userdb,"MODSTATE",0,SQLITE_UTF8,0,fn_modstate,0,0); sqlite3_create_function(userdb,"PICTURE_SIZE",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_picture_size,0,0); sqlite3_create_function(userdb,"READ_LUMP_AT",2,SQLITE_UTF8,0,fn_read_lump_at,0,0); sqlite3_create_function(userdb,"RESOURCE",-1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_resource,0,0); sqlite3_create_function(userdb,"SIGN_EXTEND",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_sign_extend,0,0); sqlite3_create_function(userdb,"SOLUTION_CACHEID",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,ptr1,fn_cacheid,0,0); sqlite3_create_module(userdb,"MESSAGES",&vt_messages,"CREATE TABLE `MESSAGES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT, `TRACE` INT);"); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | Module(vt_messages, .xColumn=vt1_messages_column, .xFilter=vt1_messages_filter, .xNext=vt1_messages_next, .xUpdate=vt1_messages_update, ); static int vt1_classes_column(sqlite3_vtab_cursor*pcur,sqlite3_context*cxt,int n) { Cursor*cur=(void*)pcur; switch(n) { case 0: // ID sqlite3_result_int64(cxt,cur->rowid); break; case 1: // NAME if(sqlite3_vtab_nochange(cxt)) return SQLITE_OK; sqlite3_result_text(cxt,classes[cur->rowid]->name,-1,0); break; case 2: // EDITORHELP if(sqlite3_vtab_nochange(cxt)) return SQLITE_OK; sqlite3_result_text(cxt,classes[cur->rowid]->edithelp,-1,0); break; case 3: // HELP if(sqlite3_vtab_nochange(cxt)) return SQLITE_OK; sqlite3_result_text(cxt,classes[cur->rowid]->gamehelp,-1,0); break; case 4: // INPUT sqlite3_result_int(cxt,classes[cur->rowid]->cflags&CF_INPUT?1:0); break; case 5: // QUIZ sqlite3_result_int(cxt,classes[cur->rowid]->cflags&CF_QUIZ?1:0); break; case 6: // TRACEIN sqlite3_result_int(cxt,classes[cur->rowid]->oflags&OF_TRACEIN?1:0); break; case 7: // TRACEOUT sqlite3_result_int(cxt,classes[cur->rowid]->oflags&OF_TRACEOUT?1:0); break; case 8: // GROUP if(sqlite3_vtab_nochange(cxt)) return SQLITE_OK; if(classes[cur->rowid]->cflags&CF_GROUP) { char*s=sqlite3_mprintf(" "); if(!s) return SQLITE_NOMEM; for(n=0;classes[cur->rowid]->codes[n];n++) { s=sqlite3_mprintf("%z%s ",s,classes[classes[cur->rowid]->codes[n]]->name); if(!s) return SQLITE_NOMEM; } sqlite3_result_text(cxt,s,-1,sqlite3_free); } else { sqlite3_result_null(cxt); } break; case 9: // PLAYER sqlite3_result_int(cxt,classes[cur->rowid]->cflags&CF_PLAYER?1:0); break; } return SQLITE_OK; } static int vt1_classes_filter(sqlite3_vtab_cursor*pcur,int idxNum,const char*idxStr,int argc,sqlite3_value**argv) { Cursor*cur=(void*)pcur; cur->eof=0; if(argc) { cur->rowid=sqlite3_value_int64(*argv); cur->unique=1; if(cur->rowid<=0 || cur->rowid>=0x4000 || !classes[cur->rowid] || classes[cur->rowid]->cflags&CF_NOCLASS2) cur->eof=1; } else { cur->unique=0; cur->rowid=1; while(cur->rowid<0x4000 && (!classes[cur->rowid] || classes[cur->rowid]->cflags&CF_NOCLASS2)) ++cur->rowid; if(cur->rowid>=0x4000) cur->eof=1; } return SQLITE_OK; } static int vt1_classes_next(sqlite3_vtab_cursor*pcur) { Cursor*cur=(void*)pcur; if(cur->unique) { cur->eof=1; } else { ++cur->rowid; while(cur->rowid<0x4000 && (!classes[cur->rowid] || classes[cur->rowid]->cflags&CF_NOCLASS2)) ++cur->rowid; if(cur->rowid>=0x4000) cur->eof=1; } return SQLITE_OK; } static int vt1_classes_update(sqlite3_vtab*vt,int argc,sqlite3_value**argv,sqlite3_int64*rowid) { sqlite3_int64 id; int v[3]; if(argc!=5 || sqlite3_value_type(*argv)!=SQLITE_INTEGER) return SQLITE_CONSTRAINT_VTAB; id=sqlite3_value_int64(*argv); if(id!=sqlite3_value_int64(argv[1])) return SQLITE_CONSTRAINT_VTAB; if(id<=0 || id>=0x4000 || !classes[id]) return SQLITE_INTERNAL; v[0]=sqlite3_value_int(argv[5]); v[1]=sqlite3_value_int(argv[6]); v[2]=sqlite3_value_int(argv[7]); if((v[0]|v[1]|v[2])&~1) return SQLITE_CONSTRAINT_CHECK; if(v[0]) classes[id]->cflags|=CF_QUIZ; else classes[id]->cflags&=~CF_QUIZ; classes[id]->oflags&=~(OF_TRACEIN|OF_TRACEOUT); classes[id]->oflags|=(v[1]?OF_TRACEIN:0)|(v[2]?OF_TRACEOUT:0); return SQLITE_OK; } Module(vt_classes, .xColumn=vt1_classes_column, .xFilter=vt1_classes_filter, .xNext=vt1_classes_next, .xUpdate=vt1_classes_update, ); void init_sql_functions(sqlite3_int64*ptr0,sqlite3_int64*ptr1) { sqlite3_create_function(userdb,"BASENAME",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_basename,0,0); sqlite3_create_function(userdb,"CLASS_DATA",2,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_class_data,0,0); sqlite3_create_function(userdb,"LEVEL_CACHEID",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,ptr0,fn_cacheid,0,0); sqlite3_create_function(userdb,"MODSTATE",0,SQLITE_UTF8,0,fn_modstate,0,0); sqlite3_create_function(userdb,"PICTURE_SIZE",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_picture_size,0,0); sqlite3_create_function(userdb,"READ_LUMP_AT",2,SQLITE_UTF8,0,fn_read_lump_at,0,0); sqlite3_create_function(userdb,"RESOURCE",-1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_resource,0,0); sqlite3_create_function(userdb,"SIGN_EXTEND",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_sign_extend,0,0); sqlite3_create_function(userdb,"SOLUTION_CACHEID",0,SQLITE_UTF8|SQLITE_DETERMINISTIC,ptr1,fn_cacheid,0,0); sqlite3_create_module(userdb,"CLASSES",&vt_classes,"CREATE TABLE `CLASSES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT, `EDITORHELP` TEXT, `HELP` TEXT," "`INPUT` INT, `QUIZ` INT, `TRACEIN` INT, `TRACEOUT` INT, `GROUP` TEXT, `PLAYER` INT);"); sqlite3_create_module(userdb,"MESSAGES",&vt_messages,"CREATE TABLE `MESSAGES`(`ID` INTEGER PRIMARY KEY, `NAME` TEXT, `TRACE` INT);"); } |
Modified heromesh.h from [2b83b24f84] to [c2593fd5ae].
︙ | ︙ | |||
98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #define OF_BUSY 0x0008 #define OF_USERSTATE 0x0010 #define OF_USERSIGNAL 0x0020 #define OF_MOVED 0x0040 #define OF_DONE 0x0080 #define OF_KEYCLEARED 0x0100 #define OF_DESTROYED 0x0200 typedef struct { const char*name; const char*edithelp; // not present if CF_GROUP const char*gamehelp; // not present if CF_GROUP Uint16*codes; // if this is CF_GROUP, then instead a zero-terminated list of classes Uint16*messages; // use 0xFFFF if no such message block; not present if CF_GROUP | > > | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #define OF_BUSY 0x0008 #define OF_USERSTATE 0x0010 #define OF_USERSIGNAL 0x0020 #define OF_MOVED 0x0040 #define OF_DONE 0x0080 #define OF_KEYCLEARED 0x0100 #define OF_DESTROYED 0x0200 #define OF_TRACEIN 0x4000 // These more properly belong in CF_ but there is room here for them #define OF_TRACEOUT 0x8000 // see above typedef struct { const char*name; const char*edithelp; // not present if CF_GROUP const char*gamehelp; // not present if CF_GROUP Uint16*codes; // if this is CF_GROUP, then instead a zero-terminated list of classes Uint16*messages; // use 0xFFFF if no such message block; not present if CF_GROUP |
︙ | ︙ |