this repo has no description
at main 1356 lines 36 kB view raw
1#include "core/core.h" 2 3#include <stdio.h> 4#include <string.h> 5#include <assert.h> 6#include "pocketpy.h" 7 8//!!! search NOTICE for v1 remains !!! 9 10/***************DEBUG SESSION*************/ 11//cmake -A x64 -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_STATIC=On -DBUILD_WITH_ALL=Off -DBUILD_WITH_PYTHON=On .. 12//for debug 13//cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_SDLGPU=On -DBUILD_WITH_ALL=On .. 14//for release 15extern bool parse_note(const char* noteStr, s32* note, s32* octave); 16static bool py_throw_error(tic_core* core, const char* msg); 17 18struct CachedNames 19{ 20 py_Name TIC; 21 py_Name BOOT; 22 py_Name SCN; 23 py_Name BDR; 24 py_Name MENU; 25} N; 26 27static tic_core* get_core() 28{ 29 void* core_pointer = py_getvmctx(); 30 if (!core_pointer) return NULL; 31 tic_core* core = (tic_core*)core_pointer; 32 assert(core_pointer!=NULL); 33 return core; 34} 35 36//set _tic_core to the given core 37static bool setup_core(tic_core* core) 38{ 39 py_newint(py_retval(), (py_i64)core); 40 py_setvmctx((void*)core); 41 return true; 42} 43 44//index should be a positive index 45//_NOTICE: py_peek(-1) takes stack.top, but pkpy.v1 takes stack.top with index 0 46//CHECKED 47static int prepare_colorindex(py_Ref index, u8* buffer) 48{ 49 if (py_istype(index, tp_int)) 50 { 51 int value; 52 value = py_toint(index); 53 54 if (value == -1) 55 return 0; 56 else 57 { 58 buffer[0] = value; 59 return 1; 60 } 61 } 62 else 63 { //should be a list then 64 int list_len = py_list_len(index); 65 list_len = (list_len < TIC_PALETTE_SIZE) ? (list_len) : (TIC_PALETTE_SIZE); 66 for (int i = 0; i < list_len; i++) 67 { 68 py_ItemRef pylist_item = py_list_getitem(index, i); 69 buffer[i] = py_toint(pylist_item); 70 } 71 return list_len; 72 } 73} 74 75/*****************TIC-80 API BEGIN*****************/ 76//API is what u bind to module "__main__" in pkpy 77//when python use func like btn(id: int) 78//it's equal to py_btn(1, [id]), which passes the arg id 79//That's an interpreter 80 81//Structure of APIs: 82//claim args 83//check arg type 84//claim tic_core + get arg 85//use api in C 86//if needed, write back result to python 87 88static bool py_btn(int argc, py_Ref argv) 89{ 90 int button_id; 91 tic_core* core = get_core(); 92 93 tic_mem* tic = (tic_mem*)core; 94 95 PY_CHECK_ARG_TYPE(0, tp_int); //check argv[0] type 96 button_id = py_toint(py_arg(0)); 97 98 //or get button_id from argv[0]? 99 //button_id = (int)py_toint(py_peek(-1)); 100 bool pressed = core->api.btn(tic, button_id & 0x1f); 101 102 py_newbool(py_retval(), pressed); 103 return true; 104} 105 106static bool py_btnp(int argc, py_Ref argv) 107{ 108 109 int button_id; 110 int hold; 111 int period; 112 113 PY_CHECK_ARG_TYPE(0, tp_int); 114 //button_id = py_toint(py_peek(-1)); 115 //hold = py_toint(py_peek(-2)); 116 //period = py_toint(py_peek(-3)); 117 button_id = py_toint(py_arg(0)); 118 hold = py_toint(py_arg(1)); 119 period = py_toint(py_arg(2)); 120 tic_core* core = get_core(); 121 122 tic_mem* tic = (tic_mem*)core; 123 124 bool pressed = core->api.btnp(tic, button_id, hold, period); 125 py_newbool(py_retval(), pressed); 126 return true; 127} 128 129static bool py_cls(int argc, py_Ref argv) 130{ 131 int color; 132 PY_CHECK_ARG_TYPE(0, tp_int); 133 tic_core* core = get_core(); 134 135 tic_mem* tic = (tic_mem*)core; 136 137 color = py_toint(py_arg(0)); 138 core->api.cls(tic, color); 139 py_assign(py_retval(), py_None()); 140 return true; 141} 142 143static bool py_spr(int argc, py_Ref argv) 144{ 145 int spr_id; 146 int x; 147 int y; 148 int color_count; 149 int scale; 150 int flip; 151 int rotate; 152 int w; 153 int h; 154 u8 colors[16]; 155 for (int i = 0; i < 9; i++) 156 PY_CHECK_ARG_TYPE(i, tp_int); 157 tic_core* core = get_core(); 158 159 tic_mem* tic = (tic_mem*)core; 160 spr_id = py_toint(py_arg(0)); 161 x = py_toint(py_arg(1)); 162 y = py_toint(py_arg(2)); 163 scale = py_toint(py_arg(4)); 164 flip = py_toint(py_arg(5)); 165 rotate = py_toint(py_arg(6)); 166 w = py_toint(py_arg(7)); 167 h = py_toint(py_arg(8)); 168 if (py_istype(py_arg(3), tp_int) || py_istype(py_arg(3), tp_list)) 169 { //it's one of the types 170 color_count = prepare_colorindex(py_arg(3), colors); 171 } 172 else 173 return TypeError("The given argument is not int or list"); 174 175 core->api.spr(tic, spr_id, x, y, w, h, colors, color_count, scale, flip, rotate); 176 py_assign(py_retval(), py_None()); 177 return true; 178} 179 180static bool py_print(int argc, py_Ref argv) 181{ 182 const char* str; 183 int x, y, color, scale; 184 bool fixed, alt; 185 186 PY_CHECK_ARG_TYPE(0, tp_str); 187 PY_CHECK_ARG_TYPE(1, tp_int); 188 PY_CHECK_ARG_TYPE(2, tp_int); 189 PY_CHECK_ARG_TYPE(3, tp_int); 190 PY_CHECK_ARG_TYPE(4, tp_bool); 191 PY_CHECK_ARG_TYPE(5, tp_int); 192 PY_CHECK_ARG_TYPE(6, tp_bool); 193 194 str = py_tostr(py_arg(0)); 195 x = py_toint(py_arg(1)); 196 y = py_toint(py_arg(2)); 197 color = py_toint(py_arg(3)); 198 fixed = py_tobool(py_arg(4)); 199 scale = py_toint(py_arg(5)); 200 alt = py_tobool(py_arg(6)); 201 tic_core* core = get_core(); 202 203 tic_mem* tic = (tic_mem*)core; 204 205 s32 ps = core->api.print(tic, str, x, y, color, fixed, scale, alt); 206 py_newint(py_retval(), ps); 207 return true; 208} 209 210static bool py_circ(int argc, py_Ref argv) 211{ 212 int x, y, radius, color; 213 for (int i = 0; i < 4; i++) 214 PY_CHECK_ARG_TYPE(i, tp_int); 215 tic_core* core = get_core(); 216 217 tic_mem* tic = (tic_mem*)core; 218 x = py_toint(py_arg(0)); 219 y = py_toint(py_arg(1)); 220 radius = py_toint(py_arg(2)); 221 color = py_toint(py_arg(3)); 222 223 core->api.circ(tic, x, y, radius, color); 224 py_assign(py_retval(), py_None()); 225 return true; 226} 227 228static bool py_circb(int argc, py_Ref argv) 229{ 230 int x, y, radius, color; 231 for (int i = 0; i < 4; i++) 232 PY_CHECK_ARG_TYPE(i, tp_int); 233 tic_core* core = get_core(); 234 235 tic_mem* tic = (tic_mem*)core; 236 x = py_toint(py_arg(0)); 237 y = py_toint(py_arg(1)); 238 radius = py_toint(py_arg(2)); 239 color = py_toint(py_arg(3)); 240 241 core->api.circb(tic, x, y, radius, color); 242 py_assign(py_retval(), py_None()); 243 return true; 244} 245 246static bool py_clip(int argc, py_Ref argv) 247{ 248 int x, y, width, height; 249 for (int i = 0; i < 4; i++) 250 PY_CHECK_ARG_TYPE(i, tp_int); 251 tic_core* core = get_core(); 252 253 tic_mem* tic = (tic_mem*)core; 254 x = py_toint(py_arg(0)); 255 y = py_toint(py_arg(1)); 256 width = py_toint(py_arg(2)); 257 height = py_toint(py_arg(3)); 258 259 core->api.clip(tic, x, y, width, height); 260 py_assign(py_retval(), py_None()); 261 return true; 262} 263 264static bool py_elli(int argc, py_Ref argv) 265{ 266 int x, y, a, b, color; 267 for (int i = 0; i < 5; i++) 268 PY_CHECK_ARG_TYPE(i, tp_int); 269 tic_core* core = get_core(); 270 271 tic_mem* tic = (tic_mem*)core; 272 x = py_toint(py_arg(0)); 273 y = py_toint(py_arg(1)); 274 a = py_toint(py_arg(2)); 275 b = py_toint(py_arg(3)); 276 color = py_toint(py_arg(4)); 277 278 core->api.elli(tic, x, y, a, b, color); 279 py_assign(py_retval(), py_None()); 280 return true; 281} 282 283static bool py_ellib(int argc, py_Ref argv) 284{ 285 int x, y, a, b, color; 286 for (int i = 0; i < 5; i++) 287 PY_CHECK_ARG_TYPE(i, tp_int); 288 tic_core* core = get_core(); 289 290 tic_mem* tic = (tic_mem*)core; 291 x = py_toint(py_arg(0)); 292 y = py_toint(py_arg(1)); 293 a = py_toint(py_arg(2)); 294 b = py_toint(py_arg(3)); 295 color = py_toint(py_arg(4)); 296 297 core->api.ellib(tic, x, y, a, b, color); 298 py_assign(py_retval(), py_None()); 299 return true; 300} 301 302static bool py_exit(int argc, py_Ref argv) 303{ 304 tic_core* core = get_core(); 305 306 tic_mem* tic = (tic_mem*)core; 307 308 core->api.exit(tic); 309 py_assign(py_retval(), py_None()); 310 return true; 311} 312 313static bool py_fget(int argc, py_Ref argv) 314{ 315 int spid, flag; 316 PY_CHECK_ARG_TYPE(0, tp_int); 317 PY_CHECK_ARG_TYPE(1, tp_int); 318 tic_core* core = get_core(); 319 320 tic_mem* tic = (tic_mem*)core; 321 spid = py_toint(py_arg(0)); 322 flag = py_toint(py_arg(1)); 323 324 bool res = core->api.fget(tic, spid, flag); 325 py_newbool(py_retval(), res); 326 327 return true; 328} 329 330static bool py_fset(int argc, py_Ref argv) 331{ 332 int spid, flag; 333 bool b; 334 PY_CHECK_ARG_TYPE(0, tp_int); 335 PY_CHECK_ARG_TYPE(1, tp_int); 336 PY_CHECK_ARG_TYPE(2, tp_bool); 337 tic_core* core = get_core(); 338 339 tic_mem* tic = (tic_mem*)core; 340 spid = py_toint(py_arg(0)); 341 flag = py_toint(py_arg(1)); 342 b = py_tobool(py_arg(2)); 343 344 core->api.fset(tic, spid, flag, b); 345 py_assign(py_retval(), py_None()); 346 return true; 347} 348 349static bool py_font(int argc, py_Ref argv) 350{ 351 const char* str; 352 int x, y, width, height, scale; 353 u8 chromakey; 354 bool fixed, alt; 355 PY_CHECK_ARG_TYPE(0, tp_str); 356 PY_CHECK_ARG_TYPE(1, tp_int); 357 PY_CHECK_ARG_TYPE(2, tp_int); 358 PY_CHECK_ARG_TYPE(3, tp_int); 359 PY_CHECK_ARG_TYPE(4, tp_int); 360 PY_CHECK_ARG_TYPE(5, tp_int); 361 PY_CHECK_ARG_TYPE(6, tp_bool); 362 PY_CHECK_ARG_TYPE(7, tp_int); 363 PY_CHECK_ARG_TYPE(8, tp_bool); 364 365 tic_core* core = get_core(); 366 367 tic_mem* tic = (tic_mem*)core; 368 str = py_tostr(py_arg(0)); 369 x = py_toint(py_arg(1)); 370 y = py_toint(py_arg(2)); 371 chromakey = (u8)py_toint(py_arg(3)); 372 width = py_toint(py_arg(4)); 373 height = py_toint(py_arg(5)); 374 fixed = py_tobool(py_arg(6)); 375 scale = py_toint(py_arg(7)); 376 alt = py_tobool(py_arg(8)); 377 378 if (scale == 0) 379 { 380 py_newint(py_retval(), 0); 381 return true; 382 } 383 384 s32 res = core->api.font(tic, str, x, y, &chromakey, 385 1, width, height, fixed, scale, alt); 386 py_newint(py_retval(), res); 387 388 return true; 389} 390 391static bool py_key(int argc, py_Ref argv) 392{ 393 int code; 394 PY_CHECK_ARG_TYPE(0, tp_int); 395 code = py_toint(py_arg(0)); 396 tic_core* core = get_core(); 397 398 tic_mem* tic = (tic_mem*)core; 399 400 if (code >= tic_keys_count) 401 { 402 return ValueError("unknown keyboard input"); 403 } 404 405 bool pressed = core->api.key(tic, code == -1 ? tic_key_unknown : code); 406 py_newbool(py_retval(), pressed); 407 408 return true; 409} 410 411static bool py_keyp(int argc, py_Ref argv) 412{ 413 int code, hold, period; 414 PY_CHECK_ARG_TYPE(0, tp_int); 415 PY_CHECK_ARG_TYPE(1, tp_int); 416 PY_CHECK_ARG_TYPE(2, tp_int); 417 code = py_toint(py_arg(0)); 418 hold = py_toint(py_arg(1)); 419 period = py_toint(py_arg(2)); 420 tic_core* core = get_core(); 421 422 tic_mem* tic = (tic_mem*)core; 423 424 if (code >= tic_keys_count) 425 { 426 return ValueError("unknown keyboard input"); 427 } 428 429 bool pressed = core->api.keyp(tic, code == -1 ? tic_key_unknown : code, hold, period); 430 py_newbool(py_retval(), pressed); 431 432 return true; 433} 434 435static bool py_line(int argc, py_Ref argv) 436{ 437 int x0, y0, x1, y1, color; 438 PY_CHECK_ARG_TYPE(0, tp_int); 439 PY_CHECK_ARG_TYPE(1, tp_int); 440 PY_CHECK_ARG_TYPE(2, tp_int); 441 PY_CHECK_ARG_TYPE(3, tp_int); 442 PY_CHECK_ARG_TYPE(4, tp_int); 443 x0 = py_toint(py_arg(0)); 444 y0 = py_toint(py_arg(1)); 445 x1 = py_toint(py_arg(2)); 446 y1 = py_toint(py_arg(3)); 447 color = py_toint(py_arg(4)); 448 tic_core* core = get_core(); 449 450 tic_mem* tic = (tic_mem*)core; 451 452 core->api.line(tic, x0, y0, x1, y1, color); 453 py_assign(py_retval(), py_None()); 454 return true; 455} 456 457//NOTICE: untested 458static void remap_callback(void* data, s32 x, s32 y, RemapResult* res) 459{ 460 py_push(py_peek(-1)); 461 py_pushnil(); 462 py_Ref x0 = py_retval(); 463 py_Ref y0 = py_retval(); 464 py_newint(x0, x); 465 py_newint(y0, y); 466 py_push(x0); 467 py_push(y0); 468 py_vectorcall(2, 0); 469 470 py_Ref list = py_retval(); 471 if (!py_checktype(list, tp_list)) return; 472 int index, flip, rotate; 473 py_ItemRef item = py_list_getitem(list, 0); 474 index = py_toint(item); 475 item = py_list_getitem(list, 1); 476 flip = py_toint(item); 477 item = py_list_getitem(list, 2); 478 rotate = py_toint(item); 479 480 res->index = (u8)index; 481 res->flip = flip; 482 res->rotate = rotate; 483} 484 485static bool py_map(int argc, py_Ref argv) 486{ 487 int x, y, w, h, sx, sy, colorkey, scale; 488 bool use_remap; 489 u8 colors[16]; 490 491 PY_CHECK_ARG_TYPE(0, tp_int); 492 PY_CHECK_ARG_TYPE(1, tp_int); 493 PY_CHECK_ARG_TYPE(2, tp_int); 494 PY_CHECK_ARG_TYPE(3, tp_int); 495 PY_CHECK_ARG_TYPE(4, tp_int); 496 PY_CHECK_ARG_TYPE(5, tp_int); 497 PY_CHECK_ARG_TYPE(7, tp_int); 498 x = py_toint(py_arg(0)); 499 y = py_toint(py_arg(1)); 500 w = py_toint(py_arg(2)); 501 h = py_toint(py_arg(3)); 502 sx = py_toint(py_arg(4)); 503 sy = py_toint(py_arg(5)); 504 if (py_istype(py_arg(6), tp_int) || py_istype(py_arg(6), tp_list)) 505 { //it's one of the types 506 colorkey = prepare_colorindex(py_arg(6), colors); 507 } 508 else 509 return TypeError("The given argument is not int or list"); 510 scale = py_toint(py_arg(7)); 511 use_remap = !py_isnone(py_arg(8)); 512 tic_core* core = get_core(); 513 514 tic_mem* tic = (tic_mem*)core; 515 516 if (use_remap) 517 core->api.map(tic, x, y, w, h, sx, sy, colors, colorkey, scale, remap_callback, core->currentVM); 518 else 519 core->api.map(tic, x, y, w, h, sx, sy, colors, colorkey, scale, NULL, NULL); 520 521 py_assign(py_retval(), py_None()); 522 return true; 523} 524 525static bool py_memcpy(int argc, py_Ref argv) 526{ 527 int dest, src, size; 528 PY_CHECK_ARG_TYPE(0, tp_int); 529 PY_CHECK_ARG_TYPE(1, tp_int); 530 PY_CHECK_ARG_TYPE(2, tp_int); 531 dest = py_toint(py_arg(0)); 532 src = py_toint(py_arg(1)); 533 size = py_toint(py_arg(2)); 534 tic_core* core = get_core(); 535 536 tic_mem* tic = (tic_mem*)core; 537 538 core->api.memcpy(tic, dest, src, size); 539 py_assign(py_retval(), py_None()); 540 return true; 541} 542 543static bool py_memset(int argc, py_Ref argv) 544{ 545 int dest, val, size; 546 PY_CHECK_ARG_TYPE(0, tp_int); 547 PY_CHECK_ARG_TYPE(1, tp_int); 548 PY_CHECK_ARG_TYPE(2, tp_int); 549 dest = py_toint(py_arg(0)); 550 val = py_toint(py_arg(1)); 551 size = py_toint(py_arg(2)); 552 tic_core* core = get_core(); 553 554 tic_mem* tic = (tic_mem*)core; 555 556 core->api.memset(tic, dest, val, size); 557 py_assign(py_retval(), py_None()); 558 return true; 559} 560 561static bool py_mget(int argc, py_Ref argv) 562{ 563 int x, y; 564 PY_CHECK_ARG_TYPE(0, tp_int); 565 PY_CHECK_ARG_TYPE(1, tp_int); 566 x = py_toint(py_arg(0)); 567 y = py_toint(py_arg(1)); 568 tic_core* core = get_core(); 569 570 tic_mem* tic = (tic_mem*)core; 571 572 int res = core->api.mget(tic, x, y); 573 py_newint(py_retval(), res); 574 return true; 575} 576 577static bool py_mset(int argc, py_Ref argv) 578{ 579 int x, y, title_id; 580 PY_CHECK_ARG_TYPE(0, tp_int); 581 PY_CHECK_ARG_TYPE(1, tp_int); 582 PY_CHECK_ARG_TYPE(2, tp_int); 583 x = py_toint(py_arg(0)); 584 y = py_toint(py_arg(1)); 585 title_id = py_toint(py_arg(2)); 586 tic_core* core = get_core(); 587 588 tic_mem* tic = (tic_mem*)core; 589 590 core->api.mset(tic, x, y, title_id); 591 py_assign(py_retval(), py_None()); 592 return true; 593} 594 595static bool py_mouse(int argc, py_Ref argv) 596{ 597 tic_core* core = get_core(); 598 599 tic_mem* tic = (tic_mem*)core; 600 601 tic_point pos = core->api.mouse(tic); 602 const tic80_mouse* mouse = &core->memory.ram->input.mouse; 603 604 //py_Ref res = (py_Ref)malloc(sizeof(py_Ref)); 605 py_Ref res = py_r7(); 606 py_newtuple(res, 7); 607 py_newint(py_tuple_getitem(res, 0), pos.x); 608 py_newint(py_tuple_getitem(res, 1), pos.y); 609 py_newint(py_tuple_getitem(res, 2), mouse->left); 610 py_newint(py_tuple_getitem(res, 3), mouse->middle); 611 py_newint(py_tuple_getitem(res, 4), mouse->right); 612 py_newint(py_tuple_getitem(res, 5), mouse->scrollx); 613 py_newint(py_tuple_getitem(res, 6), mouse->scrolly); 614 py_assign(py_retval(), res); 615 return true; 616} 617 618static bool py_music(int argc, py_Ref argv) 619{ 620 int track, frame, row, tempo, speed; 621 bool loop, sustain; 622 PY_CHECK_ARG_TYPE(0, tp_int); 623 PY_CHECK_ARG_TYPE(1, tp_int); 624 PY_CHECK_ARG_TYPE(2, tp_int); 625 PY_CHECK_ARG_TYPE(3, tp_bool); 626 PY_CHECK_ARG_TYPE(4, tp_bool); 627 PY_CHECK_ARG_TYPE(5, tp_int); 628 PY_CHECK_ARG_TYPE(6, tp_int); 629 track = py_toint(py_arg(0)); 630 frame = py_toint(py_arg(1)); 631 row = py_toint(py_arg(2)); 632 loop = py_tobool(py_arg(3)); 633 sustain = py_tobool(py_arg(4)); 634 tempo = py_toint(py_arg(5)); 635 speed = py_toint(py_arg(6)); 636 tic_core* core = get_core(); 637 638 tic_mem* tic = (tic_mem*)core; 639 640 if (track > MUSIC_TRACKS - 1) 641 { 642 return ValueError("invalid music track number"); 643 } 644 core->api.music(tic, -1, 0, 0, false, false, -1, -1); 645 core->api.music(tic, track, frame, row, loop, sustain, tempo, speed); 646 py_assign(py_retval(), py_None()); 647 return true; 648} 649 650static bool pyy_peek(int argc, py_Ref argv) 651{ 652 int addr, bits; 653 PY_CHECK_ARG_TYPE(0, tp_int); 654 PY_CHECK_ARG_TYPE(1, tp_int); 655 addr = py_toint(py_arg(0)); 656 bits = py_toint(py_arg(1)); 657 tic_core* core = get_core(); 658 659 tic_mem* tic = (tic_mem*)core; 660 661 int res = core->api.peek(tic, addr, bits); 662 py_newint(py_retval(), res); 663 return true; 664} 665 666static bool py_peek1(int argc, py_Ref argv) 667{ 668 int addr; 669 PY_CHECK_ARG_TYPE(0, tp_int); 670 addr = py_toint(py_arg(0)); 671 tic_core* core = get_core(); 672 673 tic_mem* tic = (tic_mem*)core; 674 675 int res = core->api.peek1(tic, addr); 676 py_newint(py_retval(), res); 677 return true; 678} 679 680static bool py_peek2(int argc, py_Ref argv) 681{ 682 int addr; 683 PY_CHECK_ARG_TYPE(0, tp_int); 684 addr = py_toint(py_arg(0)); 685 tic_core* core = get_core(); 686 687 tic_mem* tic = (tic_mem*)core; 688 689 int res = core->api.peek2(tic, addr); 690 py_newint(py_retval(), res); 691 return true; 692} 693 694static bool py_peek4(int argc, py_Ref argv) 695{ 696 int addr; 697 PY_CHECK_ARG_TYPE(0, tp_int); 698 addr = py_toint(py_arg(0)); 699 tic_core* core = get_core(); 700 701 tic_mem* tic = (tic_mem*)core; 702 703 int res = core->api.peek4(tic, addr); 704 py_newint(py_retval(), res); 705 return true; 706} 707 708static bool py_pix(int argc, py_Ref argv) 709{ 710 int x, y, color; 711 color = -1; 712 PY_CHECK_ARG_TYPE(0, tp_int); 713 PY_CHECK_ARG_TYPE(1, tp_int); 714 if (!py_isnone(py_arg(2))) color = py_toint(py_arg(2)); 715 x = py_toint(py_arg(0)); 716 y = py_toint(py_arg(1)); 717 tic_core* core = get_core(); 718 719 tic_mem* tic = (tic_mem*)core; 720 721 if (color >= 0) //set pixel 722 { 723 core->api.pix(tic, x, y, color, false); 724 py_assign(py_retval(), py_None()); 725 return true; 726 } 727 else //get pixel to retval 728 { 729 int res = core->api.pix(tic, x, y, 0, true); 730 py_newint(py_retval(), res); 731 return true; 732 } 733} 734 735static bool py_pmem(int argc, py_Ref argv) 736{ 737 int index, val; 738 bool has_val = false; 739 PY_CHECK_ARG_TYPE(0, tp_int); 740 if (!py_isnone(py_arg(1))) 741 { 742 has_val = true; 743 PY_CHECK_ARG_TYPE(1, tp_int); 744 val = py_toint(py_arg(1)); 745 } 746 index = py_toint(py_arg(0)); 747 tic_core* core = get_core(); 748 749 tic_mem* tic = (tic_mem*)core; 750 751 if (index >= TIC_PERSISTENT_SIZE) 752 { 753 return ValueError("invalid tic persistent index"); 754 } 755 756 int res = core->api.pmem(tic, index, 0, false); 757 py_newint(py_retval(), res); 758 759 if (has_val) 760 { 761 core->api.pmem(tic, index, val, true); 762 py_assign(py_retval(), py_None()); 763 } 764 return true; 765} 766 767static bool py_poke(int argc, py_Ref argv) 768{ 769 int addr, val, bits; 770 PY_CHECK_ARG_TYPE(0, tp_int); 771 PY_CHECK_ARG_TYPE(1, tp_int); 772 PY_CHECK_ARG_TYPE(2, tp_int); 773 addr = py_toint(py_arg(0)); 774 val = py_toint(py_arg(1)); 775 bits = py_toint(py_arg(2)); 776 tic_core* core = get_core(); 777 778 tic_mem* tic = (tic_mem*)core; 779 780 core->api.poke(tic, addr, val, bits); 781 py_assign(py_retval(), py_None()); 782 return true; 783} 784 785static bool py_poke1(int argc, py_Ref argv) 786{ 787 int addr, val; 788 PY_CHECK_ARG_TYPE(0, tp_int); 789 PY_CHECK_ARG_TYPE(1, tp_int); 790 addr = py_toint(py_arg(0)); 791 val = py_toint(py_arg(1)); 792 tic_core* core = get_core(); 793 794 tic_mem* tic = (tic_mem*)core; 795 796 core->api.poke1(tic, addr, val); 797 py_assign(py_retval(), py_None()); 798 return true; 799} 800 801static bool py_poke2(int argc, py_Ref argv) 802{ 803 int addr, val; 804 PY_CHECK_ARG_TYPE(0, tp_int); 805 PY_CHECK_ARG_TYPE(1, tp_int); 806 addr = py_toint(py_arg(0)); 807 val = py_toint(py_arg(1)); 808 tic_core* core = get_core(); 809 810 tic_mem* tic = (tic_mem*)core; 811 812 core->api.poke2(tic, addr, val); 813 py_assign(py_retval(), py_None()); 814 return true; 815} 816 817static bool py_poke4(int argc, py_Ref argv) 818{ 819 int addr, val; 820 PY_CHECK_ARG_TYPE(0, tp_int); 821 PY_CHECK_ARG_TYPE(1, tp_int); 822 addr = py_toint(py_arg(0)); 823 val = py_toint(py_arg(1)); 824 tic_core* core = get_core(); 825 826 tic_mem* tic = (tic_mem*)core; 827 828 core->api.poke4(tic, addr, val); 829 py_assign(py_retval(), py_None()); 830 return true; 831} 832 833static bool py_rect(int argc, py_Ref argv) 834{ 835 int x, y, w, h, color; 836 PY_CHECK_ARG_TYPE(0, tp_int); 837 PY_CHECK_ARG_TYPE(1, tp_int); 838 PY_CHECK_ARG_TYPE(2, tp_int); 839 PY_CHECK_ARG_TYPE(3, tp_int); 840 PY_CHECK_ARG_TYPE(4, tp_int); 841 x = py_toint(py_arg(0)); 842 y = py_toint(py_arg(1)); 843 w = py_toint(py_arg(2)); 844 h = py_toint(py_arg(3)); 845 color = py_toint(py_arg(4)); 846 tic_core* core = get_core(); 847 848 tic_mem* tic = (tic_mem*)core; 849 850 core->api.rect(tic, x, y, w, h, color); 851 py_assign(py_retval(), py_None()); 852 return true; 853} 854 855static bool py_rectb(int argc, py_Ref argv) 856{ 857 int x, y, w, h, color; 858 PY_CHECK_ARG_TYPE(0, tp_int); 859 PY_CHECK_ARG_TYPE(1, tp_int); 860 PY_CHECK_ARG_TYPE(2, tp_int); 861 PY_CHECK_ARG_TYPE(3, tp_int); 862 PY_CHECK_ARG_TYPE(4, tp_int); 863 x = py_toint(py_arg(0)); 864 y = py_toint(py_arg(1)); 865 w = py_toint(py_arg(2)); 866 h = py_toint(py_arg(3)); 867 color = py_toint(py_arg(4)); 868 tic_core* core = get_core(); 869 870 tic_mem* tic = (tic_mem*)core; 871 872 core->api.rectb(tic, x, y, w, h, color); 873 py_assign(py_retval(), py_None()); 874 return true; 875} 876 877static bool py_reset(int argc, py_Ref argv) 878{ 879 tic_core* core = get_core(); 880 881 tic_mem* tic = (tic_mem*)core; 882 883 core->api.reset(tic); 884 py_assign(py_retval(), py_None()); 885 return true; 886} 887 888static bool py_sfx(int argc, py_Ref argv) 889{ 890 int id, _note, duration, channel, volume, speed; 891 bool _parse_note = false; 892 const char* str_note; 893 PY_CHECK_ARG_TYPE(0, tp_int); 894 id = py_toint(py_arg(0)); 895 if (py_isstr(py_arg(1))) 896 { 897 _parse_note = true; 898 str_note = py_tostr(py_arg(1)); 899 } 900 else 901 { 902 PY_CHECK_ARG_TYPE(1, tp_int); 903 _note = py_toint(py_arg(1)); 904 } 905 PY_CHECK_ARG_TYPE(2, tp_int); 906 PY_CHECK_ARG_TYPE(3, tp_int); 907 PY_CHECK_ARG_TYPE(4, tp_int); 908 PY_CHECK_ARG_TYPE(5, tp_int); 909 duration = py_toint(py_arg(2)); 910 channel = py_toint(py_arg(3)); 911 volume = py_toint(py_arg(4)); 912 speed = py_toint(py_arg(5)); 913 tic_core* core = get_core(); 914 915 tic_mem* tic = (tic_mem*)core; 916 917 s32 note, octave; 918 if (_parse_note) 919 { 920 if (!parse_note(str_note, &note, &octave)) 921 { 922 return ValueError("invalid note, should be like C#4"); 923 } 924 } 925 else 926 { 927 note = _note % NOTES; 928 octave = _note / NOTES; 929 } 930 931 if (channel < 0 || channel >= TIC_SOUND_CHANNELS) 932 { 933 return ValueError("invalid channel"); 934 } 935 936 if (id >= SFX_COUNT) 937 { 938 return ValueError("invalid sfx index"); 939 } 940 941 core->api.sfx(tic, id, note, octave, duration, channel, volume & 0xf, volume & 0xf, speed); 942 py_assign(py_retval(), py_None()); 943 return true; 944} 945 946static bool py_sync(int argc, py_Ref argv) 947{ 948 int mask, bank; 949 bool tocart; 950 PY_CHECK_ARG_TYPE(0, tp_int); 951 PY_CHECK_ARG_TYPE(1, tp_int); 952 PY_CHECK_ARG_TYPE(2, tp_bool); 953 mask = py_toint(py_arg(0)); 954 bank = py_toint(py_arg(1)); 955 tocart = py_tobool(py_arg(2)); 956 tic_core* core = get_core(); 957 958 tic_mem* tic = (tic_mem*)core; 959 960 if (bank < 0 || bank >= TIC_BANKS) 961 { 962 return ValueError("invalid sync bank"); 963 } 964 965 core->api.sync(tic, mask, bank, tocart); 966 py_assign(py_retval(), py_None()); 967 return true; 968} 969 970static bool py_ttri(int argc, py_Ref argv) 971{ 972 double x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3; 973 int texsrc, chromakey; 974 double z1, z2, z3; 975 u8 colors[16]; 976 PY_CHECK_ARG_TYPE(12, tp_int); 977 if (py_istype(py_arg(13), tp_int) || py_istype(py_arg(13), tp_list)) 978 { //it's one of the types 979 chromakey = prepare_colorindex(py_arg(13), colors); 980 } 981 else 982 return TypeError("The given argument is not int or list"); 983 984 texsrc = py_toint(py_arg(12)); 985 if (!py_castfloat(py_arg(0), &x1)) return false; 986 if (!py_castfloat(py_arg(1), &y1)) return false; 987 if (!py_castfloat(py_arg(2), &x2)) return false; 988 if (!py_castfloat(py_arg(3), &y2)) return false; 989 if (!py_castfloat(py_arg(4), &x3)) return false; 990 if (!py_castfloat(py_arg(5), &y3)) return false; 991 if (!py_castfloat(py_arg(6), &u1)) return false; 992 if (!py_castfloat(py_arg(7), &v1)) return false; 993 if (!py_castfloat(py_arg(8), &u2)) return false; 994 if (!py_castfloat(py_arg(9), &v2)) return false; 995 if (!py_castfloat(py_arg(10), &u3)) return false; 996 if (!py_castfloat(py_arg(11), &v3)) return false; 997 if (!py_castfloat(py_arg(14), &z1)) return false; 998 if (!py_castfloat(py_arg(15), &z2)) return false; 999 if (!py_castfloat(py_arg(16), &z3)) return false; 1000 tic_core* core = get_core(); 1001 1002 tic_mem* tic = (tic_mem*)core; 1003 1004 core->api.ttri(tic, 1005 x1, y1, x2, y2, x3, y3, u1, v1, u2, v2, u3, v3, 1006 texsrc, 1007 colors, chromakey, 1008 z1, z2, z3, 1009 z1 != 0 || z2 != 0 || z3 != 0); 1010 py_assign(py_retval(), py_None()); 1011 return true; 1012} 1013 1014static bool py_time(int argc, py_Ref argv) 1015{ 1016 tic_core* core = get_core(); 1017 1018 tic_mem* tic = (tic_mem*)core; 1019 1020 double time = core->api.time(tic); 1021 py_newfloat(py_retval(), time); 1022 return true; 1023} 1024 1025static bool py_trace(int argc, py_Ref argv) 1026{ 1027 int color; 1028 const char* msg; 1029 PY_CHECK_ARG_TYPE(0, tp_str); 1030 PY_CHECK_ARG_TYPE(1, tp_int); 1031 msg = py_tostr(py_arg(0)); 1032 color = py_toint(py_arg(1)); 1033 tic_core* core = get_core(); 1034 1035 tic_mem* tic = (tic_mem*)core; 1036 1037 core->api.trace(tic, msg, (u8)color); 1038 py_assign(py_retval(), py_None()); 1039 return true; 1040} 1041 1042static bool py_tri(int argc, py_Ref argv) 1043{ 1044 int color; 1045 double x1, y1, x2, y2, x3, y3; 1046 PY_CHECK_ARG_TYPE(6, tp_int); 1047 if (!py_castfloat(py_arg(0), &x1)) return false; 1048 if (!py_castfloat(py_arg(1), &y1)) return false; 1049 if (!py_castfloat(py_arg(2), &x2)) return false; 1050 if (!py_castfloat(py_arg(3), &y2)) return false; 1051 if (!py_castfloat(py_arg(4), &x3)) return false; 1052 if (!py_castfloat(py_arg(5), &y3)) return false; 1053 color = py_toint(py_arg(6)); 1054 tic_core* core = get_core(); 1055 1056 tic_mem* tic = (tic_mem*)core; 1057 1058 core->api.tri(tic, x1, y1, x2, y3, x3, y3, (u8)color); 1059 py_assign(py_retval(), py_None()); 1060 return true; 1061} 1062 1063static bool py_trib(int argc, py_Ref argv) 1064{ 1065 int color; 1066 double x1, y1, x2, y2, x3, y3; 1067 PY_CHECK_ARG_TYPE(6, tp_int); 1068 if (!py_castfloat(py_arg(0), &x1)) return false; 1069 if (!py_castfloat(py_arg(1), &y1)) return false; 1070 if (!py_castfloat(py_arg(2), &x2)) return false; 1071 if (!py_castfloat(py_arg(3), &y2)) return false; 1072 if (!py_castfloat(py_arg(4), &x3)) return false; 1073 if (!py_castfloat(py_arg(5), &y3)) return false; 1074 color = py_toint(py_arg(6)); 1075 tic_core* core = get_core(); 1076 1077 tic_mem* tic = (tic_mem*)core; 1078 1079 core->api.trib(tic, x1, y1, x2, y3, x3, y3, (u8)color); 1080 py_assign(py_retval(), py_None()); 1081 return true; 1082} 1083 1084static bool py_tstamp(int argc, py_Ref argv) 1085{ 1086 tic_core* core = get_core(); 1087 1088 tic_mem* tic = (tic_mem*)core; 1089 1090 int res = core->api.tstamp(tic); 1091 py_newint(py_retval(), res); 1092 return true; 1093} 1094 1095static bool py_vbank(int argc, py_Ref argv) 1096{ 1097 int bank = -1; 1098 if (!py_isnone(py_arg(0))) 1099 { 1100 bank = py_toint(py_arg(0)); 1101 } 1102 tic_core* core = get_core(); 1103 1104 tic_mem* tic = (tic_mem*)core; 1105 1106 s32 prev = core->state.vbank.id; 1107 if (bank >= 0) 1108 { 1109 core->api.vbank(tic, bank); 1110 } 1111 py_newint(py_retval(), prev); 1112 return true; 1113} 1114 1115/*************TIC-80 MISC BEGIN****************/ 1116 1117static bool py_throw_error(tic_core* core, const char* msg) 1118{ 1119 if (msg != NULL)//reserved for TIC, BOOT et cetra 1120 { 1121 core->data->error(core->data->data, msg); 1122 } 1123 else 1124 { 1125 core->data->error(core->data->data, py_formatexc()); 1126 } 1127 return false; 1128} 1129 1130static bool bind_pkpy_v2() 1131{ 1132 py_GlobalRef mod = py_getmodule("__main__"); 1133 py_bind(mod, "btn(id: int) -> bool", py_btn); 1134 py_bind(mod, "btnp(id: int, hold=-1, period=-1) -> bool", py_btnp); 1135 py_bind(mod, "cls(color=0)", py_cls); 1136 py_bind(mod, "spr(id: int, x: int, y: int, colorkey=-1, scale=1, flip=0, rotate=0, w=1, h=1)", 1137 py_spr); 1138 py_bind(mod, "print(text, x=0, y=0, color=15, fixed=False, scale=1, alt=False)", py_print); 1139 py_bind(mod, "circ(x: int, y: int, radius: int, color: int)", py_circ); 1140 py_bind(mod, "circb(x: int, y: int, radius: int, color: int)", py_circb); 1141 py_bind(mod, "clip(x: int, y: int, width: int, height: int)", py_clip); 1142 py_bind(mod, "elli(x: int, y: int, a: int, b: int, color: int)", py_elli); 1143 py_bind(mod, "ellib(x: int, y: int, a: int, b: int, color: int)", py_ellib); 1144 py_bind(mod, "exit()", py_exit); 1145 py_bind(mod, "fget(sprite_id: int, flag: int) -> bool", py_fget); 1146 py_bind(mod, "fset(sprite_id: int, flag: int, b: bool)", py_fset); 1147 py_bind(mod, "font(text: str, x: int, y: int, chromakey: int, char_width=8, char_height=8, fixed=False, scale=1, alt=False) -> int", py_font); 1148 py_bind(mod, "key(code=-1) -> bool", py_key); 1149 py_bind(mod, "keyp(code=-1, hold=-1, period=-17) -> int", py_keyp); 1150 py_bind(mod, "line(x0: int, y0: int, x1: int, y1: int, color: int)", py_line); 1151 py_bind(mod, "map(x=0, y=0, w=30, h=17, sx=0, sy=0, colorkey=-1, scale=1, remap=None)", py_map); 1152 py_bind(mod, "memcpy(dest: int, source: int, size: int)", py_memcpy); 1153 py_bind(mod, "memset(dest: int, value: int, size: int)", py_memset); 1154 py_bind(mod, "mget(x: int, y: int) -> int", py_mget); 1155 py_bind(mod, "mset(x: int, y: int, tile_id: int)", py_mset); 1156 py_bind(mod, "mouse() -> tuple[int, int, bool, bool, bool, int, int]", py_mouse); 1157 py_bind(mod, "music(track=-1, frame=-1, row=-1, loop=True, sustain=False, tempo=-1, speed=-1)", py_music); 1158 py_bind(mod, "peek(addr: int, bits=8) -> int", pyy_peek); 1159 py_bind(mod, "peek1(addr: int) -> int", py_peek1); 1160 py_bind(mod, "peek2(addr: int) -> int", py_peek2); 1161 py_bind(mod, "peek4(addr: int) -> int", py_peek4); 1162 py_bind(mod, "pix(x: int, y: int, color: int=None) -> int | None", py_pix); 1163 py_bind(mod, "pmem(index: int, value: int=None) -> int", py_pmem); 1164 py_bind(mod, "poke(addr: int, value: int, bits=8)", py_poke); 1165 py_bind(mod, "poke1(addr: int, value: int)", py_poke1); 1166 py_bind(mod, "poke2(addr: int, value: int)", py_poke2); 1167 py_bind(mod, "poke4(addr: int, value: int)", py_poke4); 1168 py_bind(mod, "rect(x: int, y: int, w: int, h: int, color: int)", py_rect); 1169 py_bind(mod, "rectb(x: int, y: int, w: int, h: int, color: int)", py_rectb); 1170 py_bind(mod, "reset()", py_reset); 1171 py_bind(mod, "sfx(id: int, note=-1, duration=-1, channel=0, volume=15, speed=0)", py_sfx); 1172 py_bind(mod, "sync(mask=0, bank=0, tocart=False)", py_sync); 1173 py_bind(mod, "ttri(x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, u1: float, v1: float, u2: float, v2: float, u3: float, v3: float, texsrc=0, chromakey=-1, z1=0.0, z2=0.0, z3=0.0)", py_ttri); 1174 py_bind(mod, "time() -> int", py_time); 1175 py_bind(mod, "trace(message, color=15)", py_trace); 1176 py_bind(mod, "tri(x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, color: int)", py_tri); 1177 py_bind(mod, "trib(x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, color: int)", py_trib); 1178 py_bind(mod, "tstamp() -> int", py_tstamp); 1179 py_bind(mod, "vbank(bank: int=None) -> int", py_vbank); 1180 return true; 1181} 1182 1183void close_pkpy_v2(tic_mem* tic) 1184{ 1185 tic_core* core = (tic_core*)tic; 1186 if (core->currentVM) 1187 { 1188 core->currentVM = NULL; 1189 py_resetvm(); 1190 //py_initialize();//reset 1191 } 1192} 1193 1194static bool init_pkpy_v2(tic_mem* tic, const char* code) 1195{ 1196 //maybe some config here 1197 py_initialize(); 1198 tic_core* core = (tic_core*)tic; 1199 close_pkpy_v2(tic); 1200 N.TIC = py_name("TIC"); 1201 N.BOOT = py_name("BOOT"); 1202 N.SCN = py_name("SCN"); 1203 N.BDR = py_name("BDR"); 1204 N.MENU = py_name("MENU"); 1205 1206 setup_core(core); 1207 core->currentVM = (void*)py_retval(); 1208 if (!bind_pkpy_v2()) 1209 { 1210 return RuntimeError("Binding func failed"); 1211 } 1212 if (!py_exec(code, "main.py", EXEC_MODE, NULL)) 1213 { 1214 //throw error 1215 return py_throw_error(core, NULL); 1216 } 1217 return true; 1218} 1219 1220void tick_pkpy_v2(tic_mem* tic) 1221{ 1222 tic_core* core = (tic_core*)tic; 1223 if (!core->currentVM) return; //no vm 1224 1225 py_GlobalRef py_tick = py_getglobal(N.TIC); 1226 if (!py_tick) return; 1227 py_push(py_tick); 1228 py_pushnil(); 1229 if (!py_vectorcall(0, 0)) 1230 { 1231 py_throw_error(core, "TIC running error!"); 1232 } 1233} 1234 1235void boot_pkpy_v2(tic_mem* tic) 1236{ 1237 tic_core* core = (tic_core*)tic; 1238 if (!core->currentVM) return; //no vm 1239 1240 py_GlobalRef py_boot = py_getglobal(N.BOOT); 1241 if (!py_boot) return; 1242 py_push(py_boot); 1243 py_pushnil(); 1244 if (!py_vectorcall(0, 0)) 1245 { 1246 py_throw_error(core, "BOOT running error!"); 1247 } 1248} 1249 1250void callback_scanline(tic_mem* tic, s32 row, void* data) 1251{ 1252 tic_core* core = (tic_core*)tic; 1253 if (!core->currentVM) return; //no vm 1254 1255 py_GlobalRef py_scn = py_getglobal(N.SCN); 1256 if (!py_scn) return; 1257 py_push(py_scn); 1258 py_pushnil(); 1259 py_Ref py_row = py_retval(); 1260 py_newint(py_row, row); 1261 py_push(py_row); 1262 if (!py_vectorcall(1, 0)) 1263 { 1264 py_throw_error(core, "SCANLINE running error!"); 1265 } 1266} 1267 1268void callback_border(tic_mem* tic, s32 row, void* data) 1269{ 1270 tic_core* core = (tic_core*)tic; 1271 if (!core->currentVM) return; //no vm 1272 1273 py_GlobalRef py_bdr = py_getglobal(N.BDR); 1274 if (!py_bdr) return; 1275 py_push(py_bdr); 1276 py_pushnil(); 1277 py_Ref py_row = py_retval(); 1278 py_newint(py_row, row); 1279 py_push(py_row); 1280 if (!py_vectorcall(1, 0)) 1281 { 1282 py_throw_error(core, "BORDER running error!"); 1283 } 1284} 1285void callback_menu(tic_mem* tic, s32 index, void* data) 1286{ 1287 tic_core* core = (tic_core*)tic; 1288 if (!core->currentVM) return; //no vm 1289 1290 py_GlobalRef py_menu = py_getglobal(N.MENU); 1291 if (!py_menu) return; 1292 py_push(py_menu); 1293 py_pushnil(); 1294 py_Ref py_idx = py_retval(); 1295 py_newint(py_idx, index); 1296 py_push(py_idx); 1297 if (!py_vectorcall(1, 0)) 1298 { 1299 py_throw_error(core, "MENU running error!"); 1300 } 1301} 1302 1303static const char* const PythonKeywords[] = 1304 { 1305 "is not", "not in", "yield from", 1306 "class", "import", "as", "def", "lambda", "pass", "del", "from", "with", "yield", 1307 "None", "in", "is", "and", "or", "not", "True", "False", "global", "try", "except", "finally", 1308 "while", "for", "if", "elif", "else", "break", "continue", "return", "assert", "raise"}; 1309 1310static const u8 DemoRom[] = 1311 { 1312#include "../build/assets/pythondemo.tic.dat" 1313}; 1314 1315static const u8 MarkRom[] = 1316 { 1317#include "../build/assets/pythonmark.tic.dat" 1318}; 1319 1320TIC_EXPORT const tic_script EXPORT_SCRIPT(Python) = 1321 { 1322 .id = 20, 1323 .name = "python", 1324 .fileExtension = ".py", 1325 .projectComment = "#", 1326 .init = init_pkpy_v2, 1327 .close = close_pkpy_v2, 1328 .tick = tick_pkpy_v2, 1329 .boot = boot_pkpy_v2, 1330 1331 .callback = 1332 { 1333 .scanline = callback_scanline, 1334 .border = callback_border, 1335 .menu = callback_menu, 1336 }, 1337 1338 .getOutline = NULL, 1339 .eval = NULL, 1340 //above is a must need 1341 .blockCommentStart = NULL, 1342 .blockCommentEnd = NULL, 1343 .blockCommentStart2 = NULL, 1344 .blockCommentEnd2 = NULL, 1345 .singleComment = "#", 1346 .blockStringStart = NULL, 1347 .blockStringEnd = NULL, 1348 .blockEnd = NULL, 1349 .stdStringStartEnd = "'\"", 1350 1351 .keywords = PythonKeywords, 1352 .keywordsCount = COUNT_OF(PythonKeywords), 1353 1354 .demo = {DemoRom, sizeof DemoRom}, 1355 .mark = {MarkRom, sizeof MarkRom, "pythonmark.tic"}, 1356};