Overview
Comment: | Implement FlushClass, FlushObj, and IgnoreKey. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
ccfd090a7aa4005d37e4ca09a148fd1b |
User & Date: | user on 2020-12-14 22:30:06 |
Other Links: | manifest | tags |
Context
2020-12-14
| ||
22:31 | Handle departures/arrivals while the object is not linked into the playfield, so that it doesn't trigger itself check-in: cfacb2c35a user: user tags: trunk | |
22:30 | Implement FlushClass, FlushObj, and IgnoreKey. check-in: ccfd090a7a user: user tags: trunk | |
08:24 | Implement the tuck instruction check-in: 7f3d502de0 user: user tags: trunk | |
Changes
Modified exec.c from [7a9b812f58] to [c7401d76bd].
︙ | ︙ | |||
37 38 39 40 41 42 43 | Uint32 from; Value arg1,arg2,arg3; } MessageVars; static jmp_buf my_env; static const char*my_error; static MessageVars msgvars; | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | Uint32 from; Value arg1,arg2,arg3; } MessageVars; static jmp_buf my_env; static const char*my_error; static MessageVars msgvars; static char lastimage_processing,changed,all_flushed; static Value vstack[VSTACKSIZE]; static int vstackptr; static const char*traceprefix; static Uint8 current_key; #define Throw(x) (my_error=(x),longjmp(my_env,1)) #define StackReq(x,y) do{ if(vstackptr<(x)) Throw("Stack underflow"); if(vstackptr-(x)+(y)>=VSTACKSIZE) Throw("Stack overflow"); }while(0) |
︙ | ︙ | |||
524 525 526 527 528 529 530 | m=p->up; } } } if(!(o->oflags&OF_VISUALONLY)) { m=objects[n]->up; if(m!=VOIDLINK) { | | | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 | m=p->up; } } } if(!(o->oflags&OF_VISUALONLY)) { m=objects[n]->up; if(m!=VOIDLINK) { v=send_message(VOIDLINK,n,MSG_SUNK,NVALUE(0),NVALUE(0),NVALUE(0)); while(m!=VOIDLINK) { send_message(n,m,MSG_FLOATED,NVALUE(0),NVALUE(0),v); m=objects[m]->up; } } } // The OF_MOVED flag is set elsewhere, not here |
︙ | ︙ | |||
565 566 567 568 569 570 571 572 573 574 575 576 577 578 | o=objects[t0.u]; printf(" [$%s %d %d]",classes[o->class]->name,o->x,o->y); } o=objects[obj]; printf(" : %u %u [$%s %d %d]",o->generation,obj,classes[o->class]->name,o->x,o->y); printf(" : %u %u : %u %u\n",t1.t,t1.u,t2.t,t2.u); } static inline Value v_broadcast(Uint32 from,Value c,Value msg,Value arg1,Value arg2,Value arg3,int s) { if(msg.t!=TY_MESSAGE) Throw("Type mismatch"); if(c.t!=TY_CLASS && (c.t!=TY_NUMBER || c.u)) Throw("Type mismatch"); return NVALUE(broadcast(from,c.u,msg.u,arg1,arg2,arg3,s)); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 | o=objects[t0.u]; printf(" [$%s %d %d]",classes[o->class]->name,o->x,o->y); } o=objects[obj]; printf(" : %u %u [$%s %d %d]",o->generation,obj,classes[o->class]->name,o->x,o->y); printf(" : %u %u : %u %u\n",t1.t,t1.u,t2.t,t2.u); } static void flush_object(Uint32 n) { Object*o=objects[n]; o->arrived=o->arrived2=o->departed=o->departed2=0; o->oflags&=~(OF_MOVED|OF_BUSY|OF_USERSIGNAL); o->inertia=0; } static void flush_class(Uint16 c) { Uint32 n,p; Object*o; if(lastobj==VOIDLINK) return; n=lastobj; while(o=objects[n]) { p=o->prev; if(!c || o->class==c) { o->arrived=o->arrived2=o->departed=o->departed2=0; o->oflags&=~(OF_MOVED|OF_BUSY|OF_USERSIGNAL); o->inertia=0; } if(p==VOIDLINK) break; n=p; } } static inline void flush_all(void) { if(current_key) all_flushed=1; flush_class(0); } static inline Value v_broadcast(Uint32 from,Value c,Value msg,Value arg1,Value arg2,Value arg3,int s) { if(msg.t!=TY_MESSAGE) Throw("Type mismatch"); if(c.t!=TY_CLASS && (c.t!=TY_NUMBER || c.u)) Throw("Type mismatch"); return NVALUE(broadcast(from,c.u,msg.u,arg1,arg2,arg3,s)); } |
︙ | ︙ | |||
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 | case OP_DONE_C: StackReq(1,1); GetFlagOf(OF_DONE); break; case OP_DONE_E: StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_DONE; else o->oflags&=~OF_BUSY; break; case OP_DONE_EC: StackReq(2,0); SetFlagOf(OF_DONE); break; case OP_DROP: StackReq(1,0); Pop(); break; case OP_DROP_D: StackReq(2,0); Pop(); Pop(); break; case OP_DUP: StackReq(1,2); t1=Pop(); Push(t1); Push(t1); break; case OP_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break; case OP_FOR: NoIgnore(); StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); ptr=v_for(code,ptr,t1,t2,t3); break; case OP_FROM: StackReq(0,1); Push(OVALUE(msgvars.from)); break; case OP_GE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?0:1)); break; case OP_GE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?0:1)); break; case OP_GOTO: ptr=code[ptr]; break; case OP_GT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t1,t2)?1:0)); break; case OP_GT_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t1,t2)?1:0)); break; case OP_HARD: StackReq(1,1); j=v_sh_dir(Pop()); Push(NVALUE(o->hard[j])); break; case OP_HARD_C: StackReq(2,1); j=v_sh_dir(Pop()); Push(GetVariableOrAttributeOf(hard[j],NVALUE)); break; case OP_HARD_E: NoIgnore(); StackReq(2,0); j=v_sh_dir(Pop()); t1=Pop(); Numeric(t1); o->hard[j]=t1.u; break; case OP_HARD_EC: NoIgnore(); StackReq(3,0); j=v_sh_dir(Pop()); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->hard[j]=t1.u; break; case OP_HEIGHT: StackReq(0,1); Push(NVALUE(o->height)); break; case OP_HEIGHT_C: StackReq(1,1); Push(GetVariableOrAttributeOf(height,NVALUE)); break; case OP_HEIGHT_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u; break; case OP_HEIGHT_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u&0xFFFF; break; case OP_HEIGHT_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->height=t1.u; break; case OP_HEIGHT_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->height=t1.u; break; case OP_IF: StackReq(1,0); if(v_bool(Pop())) ptr++; else ptr=code[ptr]; break; case OP_IMAGE: StackReq(0,1); Push(NVALUE(o->image)); break; case OP_IMAGE_C: StackReq(1,1); Push(GetVariableOf(image,NVALUE)); break; case OP_IMAGE_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->image=t1.u; break; case OP_IMAGE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->image=t1.u; break; case OP_INERTIA: StackReq(0,1); Push(NVALUE(o->inertia)); break; case OP_INERTIA_C: StackReq(1,1); Push(GetVariableOf(inertia,NVALUE)); break; case OP_INERTIA_E: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u; break; | > > > | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 | case OP_DONE_C: StackReq(1,1); GetFlagOf(OF_DONE); break; case OP_DONE_E: StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_DONE; else o->oflags&=~OF_BUSY; break; case OP_DONE_EC: StackReq(2,0); SetFlagOf(OF_DONE); break; case OP_DROP: StackReq(1,0); Pop(); break; case OP_DROP_D: StackReq(2,0); Pop(); Pop(); break; case OP_DUP: StackReq(1,2); t1=Pop(); Push(t1); Push(t1); break; case OP_EQ: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_equal(t1,t2)?1:0)); break; case OP_FLUSHCLASS: NoIgnore(); StackReq(1,0); t1=Pop(); if(t1.t==TY_CLASS) flush_class(t1.u); else if(t1.t==TY_NUMBER && t1.s==-1) flush_all(); else if(t1.t) Throw("Type mismatch"); break; case OP_FLUSHOBJ: NoIgnore(); StackReq(1,0); i=v_object(Pop()); if(i!=VOIDLINK) flush_object(i); break; case OP_FOR: NoIgnore(); StackReq(3,1); t3=Pop(); t2=Pop(); t1=Pop(); ptr=v_for(code,ptr,t1,t2,t3); break; case OP_FROM: StackReq(0,1); Push(OVALUE(msgvars.from)); break; case OP_GE: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t2,t1)?0:1)); break; case OP_GE_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t2,t1)?0:1)); break; case OP_GOTO: ptr=code[ptr]; break; case OP_GT: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_unsigned_greater(t1,t2)?1:0)); break; case OP_GT_C: StackReq(2,1); t2=Pop(); t1=Pop(); Push(NVALUE(v_signed_greater(t1,t2)?1:0)); break; case OP_HARD: StackReq(1,1); j=v_sh_dir(Pop()); Push(NVALUE(o->hard[j])); break; case OP_HARD_C: StackReq(2,1); j=v_sh_dir(Pop()); Push(GetVariableOrAttributeOf(hard[j],NVALUE)); break; case OP_HARD_E: NoIgnore(); StackReq(2,0); j=v_sh_dir(Pop()); t1=Pop(); Numeric(t1); o->hard[j]=t1.u; break; case OP_HARD_EC: NoIgnore(); StackReq(3,0); j=v_sh_dir(Pop()); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->hard[j]=t1.u; break; case OP_HEIGHT: StackReq(0,1); Push(NVALUE(o->height)); break; case OP_HEIGHT_C: StackReq(1,1); Push(GetVariableOrAttributeOf(height,NVALUE)); break; case OP_HEIGHT_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u; break; case OP_HEIGHT_E16: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->height=t1.u&0xFFFF; break; case OP_HEIGHT_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->height=t1.u; break; case OP_HEIGHT_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->height=t1.u; break; case OP_IF: StackReq(1,0); if(v_bool(Pop())) ptr++; else ptr=code[ptr]; break; case OP_IGNOREKEY: if(current_key) key_ignored=all_flushed=1; break; case OP_IMAGE: StackReq(0,1); Push(NVALUE(o->image)); break; case OP_IMAGE_C: StackReq(1,1); Push(GetVariableOf(image,NVALUE)); break; case OP_IMAGE_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->image=t1.u; break; case OP_IMAGE_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) objects[i]->image=t1.u; break; case OP_INERTIA: StackReq(0,1); Push(NVALUE(o->inertia)); break; case OP_INERTIA_C: StackReq(1,1); Push(GetVariableOf(inertia,NVALUE)); break; case OP_INERTIA_E: StackReq(1,0); t1=Pop(); Numeric(t1); o->inertia=t1.u; break; |
︙ | ︙ | |||
909 910 911 912 913 914 915 916 917 918 919 | case OP_STRENGTH_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break; case OP_STRENGTH_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break; case OP_SOUND: StackReq(2,0); t2=Pop(); t1=Pop(); break; // Sound not implemented at this time case OP_SUB: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u-t2.u)); break; case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break; case OP_TRACE: StackReq(3,0); trace_stack(obj); break; case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break; case OP_USERSTATE: StackReq(0,1); if(o->oflags&OF_USERSTATE) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_USERSTATE_C: StackReq(1,1); GetFlagOf(OF_USERSTATE); break; case OP_USERSTATE_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSTATE; else o->oflags&=~OF_USERSTATE; break; case OP_USERSTATE_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSTATE); break; | > > > > < < < < | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 | case OP_STRENGTH_EC: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break; case OP_STRENGTH_EC16: NoIgnore(); StackReq(2,0); t1=Pop(); Numeric(t1); i=v_object(Pop()); if(i!=VOIDLINK) o->strength=t1.u; break; case OP_SOUND: StackReq(2,0); t2=Pop(); t1=Pop(); break; // Sound not implemented at this time case OP_SUB: StackReq(2,1); t2=Pop(); Numeric(t2); t1=Pop(); Numeric(t1); Push(NVALUE(t1.u-t2.u)); break; case OP_SWAP: StackReq(2,2); t1=Pop(); t2=Pop(); Push(t1); Push(t2); break; case OP_TRACE: StackReq(3,0); trace_stack(obj); break; case OP_TUCK: StackReq(2,3); t2=Pop(); t1=Pop(); Push(t2); Push(t1); Push(t2); break; case OP_USERSIGNAL: StackReq(0,1); if(o->oflags&OF_USERSIGNAL) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_USERSIGNAL_C: StackReq(1,1); GetFlagOf(OF_USERSIGNAL); break; case OP_USERSIGNAL_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSIGNAL; else o->oflags&=~OF_USERSIGNAL; break; case OP_USERSIGNAL_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSIGNAL); break; case OP_USERSTATE: StackReq(0,1); if(o->oflags&OF_USERSTATE) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_USERSTATE_C: StackReq(1,1); GetFlagOf(OF_USERSTATE); break; case OP_USERSTATE_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_USERSTATE; else o->oflags&=~OF_USERSTATE; break; case OP_USERSTATE_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_USERSTATE); break; case OP_VISUALONLY: StackReq(0,1); if(o->oflags&OF_VISUALONLY) Push(NVALUE(1)); else Push(NVALUE(0)); break; case OP_VISUALONLY_C: StackReq(1,1); GetFlagOf(OF_VISUALONLY); break; case OP_VISUALONLY_E: NoIgnore(); StackReq(1,0); if(v_bool(Pop())) o->oflags|=OF_VISUALONLY; else o->oflags&=~OF_VISUALONLY; break; case OP_VISUALONLY_EC: NoIgnore(); StackReq(2,0); SetFlagOf(OF_VISUALONLY); break; case OP_VOLUME: StackReq(0,1); Push(NVALUE(o->volume)); break; case OP_VOLUME_C: StackReq(1,1); Push(GetVariableOrAttributeOf(volume,NVALUE)); break; case OP_VOLUME_E: NoIgnore(); StackReq(1,0); t1=Pop(); Numeric(t1); o->volume=t1.u; break; |
︙ | ︙ | |||
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 | } const char*execute_turn(int key) { Uint32 n; if(setjmp(my_env)) return my_error; changed=0; key_ignored=0; lastimage_processing=0; vstackptr=0; current_key=key; for(n=0;n<nobjects;n++) if(objects[n]) { objects[n]->distance=0; objects[n]->oflags&=~(OF_KEYCLEARED|OF_DONE); } if(key_ignored && changed) return "Invalid use of IgnoreKey"; current_key=0; | > < > | 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 | } const char*execute_turn(int key) { Uint32 n; if(setjmp(my_env)) return my_error; changed=0; key_ignored=0; all_flushed=0; lastimage_processing=0; vstackptr=0; current_key=key; for(n=0;n<nobjects;n++) if(objects[n]) { objects[n]->distance=0; objects[n]->oflags&=~(OF_KEYCLEARED|OF_DONE); } if(key_ignored && changed) return "Invalid use of IgnoreKey"; current_key=0; if(generation_number<=TY_MAXTYPE) return "Too many generations of objects"; return 0; } const char*init_level(void) { if(setjmp(my_env)) return my_error; if(main_options['t']) printf("[Level %d restarted]\n",level_id); memcpy(globals,initglobals,sizeof(globals)); gameover=0; changed=0; key_ignored=0; all_flushed=0; lastimage_processing=0; vstackptr=0; move_number=0; current_key=0; broadcast(VOIDLINK,0,MSG_INIT,NVALUE(0),NVALUE(0),NVALUE(0),0); broadcast(VOIDLINK,0,MSG_POSTINIT,NVALUE(0),NVALUE(0),NVALUE(0),0); if(generation_number<=TY_MAXTYPE) return "Too many generations of objects"; return 0; } |