generate platform_ops.h from platform_ops.proto, and reduce dependencies
[proto.git] / src / sim / kernel_extension.cpp
blobf19bc67403efc54b0db7b62f63be4167931dfc5a
1 /* Simulator's extensions to the kernel
2 Copyright (C) 2005-2008, Jonathan Bachrach, Jacob Beal, and contributors
3 listed in the AUTHORS file in the MIT Proto distribution's top directory.
5 This file is part of MIT Proto, and is distributed under the terms of
6 the GNU General Public License, with a linking exception, as described
7 in the file LICENSE in the MIT Proto distribution's top directory. */
9 #include "config.h"
10 #include <stdlib.h>
11 #include "proto.h"
12 #include "proto_vm.h"
13 #include "platform_ops.h"
15 INLINE void slider_exec (VOID) {
16 int dkey = (int)NUM_PEEK(5);
17 int ikey = (int)NUM_PEEK(4);
18 NUM_VAL init = NUM_PEEK(3);
19 NUM_VAL incr = NUM_PEEK(2);
20 NUM_VAL min = NUM_PEEK(1);
21 NUM_VAL max = NUM_PEEK(0);
22 NPOP(6); NUM_PUSH(read_slider(dkey, ikey, init, incr, min, max));
25 #define CLIP(x, min, max) MAX(min, MIN(max, x))
27 static void hsv_to_rgb (flo h, flo s, flo v, flo *r, flo *g, flo *b) {
28 flo rt = 0, gt = 0, bt = 0;
29 s = CLIP(s, 0, 1);
30 if (s == 0.0) {
31 rt = gt = bt = v;
32 } else {
33 int i;
34 flo h_temp = (h == 360.0) ? 0.0 : h;
35 flo f, p, q, t;
36 h_temp /= 60.0;
37 i = (int)h_temp;
38 f = h_temp - i;
39 p = v*(1-s);
40 q = v*(1-(s*f));
41 t = v*(1-(s*(1-f)));
42 switch (i) {
43 case 0: rt = v; gt = t; bt = p; break;
44 case 1: rt = q; gt = v; bt = p; break;
45 case 2: rt = p; gt = v; bt = t; break;
46 case 3: rt = p; gt = q; bt = v; break;
47 case 4: rt = t; gt = p; bt = v; break;
48 case 5: rt = v; gt = p; bt = q; break;
51 *r = rt; *g = gt; *b = bt;
54 MAYBE_INLINE DATA *vec_elt (VEC_VAL *vec, int i) {
55 if (i < 0 || i >= vec->n)
56 uerror("UNBOUND VEC ELT %d > %d\n", i, vec->n);
57 return &vec->elts[i];
60 INLINE NUM_VAL num_vec_elt (VEC_VAL *v, int i) { return NUM_GET(vec_elt(v, i)); }
61 INLINE NUM_VAL num_vec_elt_set (VEC_VAL *v, int i, NUM_VAL x) { return NUM_SET(vec_elt(v, i), x); }
63 void hsv_exec (int off) {
64 VEC_VAL *rgb = VEC_GET(GLO_GET(off));
65 VEC_VAL *hsv = VEC_PEEK(0);
66 flo r, g, b;
67 hsv_to_rgb
68 (num_vec_elt(hsv, 0), num_vec_elt(hsv, 1), num_vec_elt(hsv, 2), &r, &g, &b);
69 num_vec_elt_set(rgb, 0, r);
70 num_vec_elt_set(rgb, 1, g);
71 num_vec_elt_set(rgb, 2, b);
72 NPOP(1); VEC_PUSH(rgb);
75 void my_platform_operation(uint8_t op) {
76 MACHINE *m = machine;
77 switch(op) {
78 case DIE_OP:
79 die(NUM_PEEK(0)); break;
80 case CLONE_OP:
81 clone_machine(NUM_PEEK(0)); break;
82 case COORD_OP:
83 VEC_PUSH(read_coord_sensor()); break;
84 case RANGER_OP:
85 VEC_PUSH(read_ranger()); break;
86 case SENSE_OP:
87 NUM_PUSH(read_sensor((int)NUM_POP())); break;
88 case BUTTON_OP:
89 NUM_PUSH(read_button((int)NUM_POP())); break;
90 case SLIDER_OP:
91 slider_exec(); break;
92 case LIGHT_OP:
93 NUM_PUSH(read_light_sensor()); break;
94 case SOUND_OP:
95 NUM_PUSH(read_microphone()); break;
96 case SPEAK_OP:
97 set_speak(NUM_PEEK(0)); break;
98 case TEMP_OP:
99 NUM_PUSH(read_temp()); break;
100 case MOUSE_OP:
101 VEC_PUSH(read_mouse_sensor()); break;
102 case CONDUCTIVE_OP:
103 NUM_PUSH(read_short()); break;
104 case LOCAL_FOLD_OP: {
105 int k = (int)NUM_PEEK(0);
106 int val = (BOOL)NUM_PEEK(1);
107 set_is_folding((int)NUM_PEEK(1), k);
108 NPOP(2); NUM_PUSH(val); break; }
109 case FOLD_COMPLETE_OP: {
110 int k = (int)NUM_PEEK(0);
111 NPOP(1); NUM_PUSH(read_fold_complete(k)); break; }
112 case LEDS_OP: {
113 NUM_VAL val = NUM_PEEK(0);
114 set_b_led((val > 0.25) != 0 ? 1.0 : 0);
115 set_g_led((val > 0.50) != 0 ? 1.0 : 0);
116 set_r_led((val > 0.75) != 0 ? 1.0 : 0);
117 break; }
118 case RED_OP:
119 set_r_led(NUM_PEEK(0)); break;
120 case GREEN_OP:
121 set_g_led(NUM_PEEK(0)); break;
122 case BLUE_OP:
123 set_b_led(NUM_PEEK(0)); break;
124 case RGB_OP: {
125 VEC_VAL *vec = VEC_PEEK(0);
126 set_r_led(num_vec_elt(vec, 0));
127 set_g_led(num_vec_elt(vec, 1));
128 set_b_led(num_vec_elt(vec, 2));
129 break; }
130 case HSV_OP:
131 hsv_exec(NXT_OP(m)); break;
132 case RADIUS_SET_OP:
133 radius_set(NUM_PEEK(0)); break;
134 case RADIUS_OP:
135 NUM_PUSH(radius_get()); break;
136 case BUMP_OP:
137 NUM_PUSH(read_bump()); break;
138 case CHANNEL_OP: {
139 int n = NXT_OP(m);
140 set_channel(NUM_POP(), n); NUM_PUSH(n); break; }
141 case DRIP_OP: {
142 NUM_VAL a = NUM_PEEK(1);
143 NUM_VAL c = NUM_PEEK(0);
144 NPOP(2); NUM_PUSH(drip_channel(a, (int)c));
145 break; }
146 case CONCENTRATION_OP:
147 NUM_PUSH(read_channel((int)NUM_POP())); break;
148 case CHANNEL_GRAD_OP:
149 VEC_PUSH(grad_channel((int)NUM_POP())); break;
150 case CAM_OP:
151 NUM_PUSH(cam_get((int)NUM_POP())); break;
152 default:
153 uerror("UNKNOWN OPCODE %d\n", op);