-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DEL.X / DEL.R ops #164
DEL.X / DEL.R ops #164
Changes from 10 commits
5296d2e
90cea46
1f47cc7
71a9616
e31d306
b50f2d8
f0bfd37
ec7aacf
7beff19
1fd3574
4151cdf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,35 +4,58 @@ | |
#include "teletype.h" | ||
#include "teletype_io.h" | ||
|
||
static void delay_common_add(scene_state_t *ss, exec_state_t *es, int16_t i, | ||
int16_t delay_time, | ||
const tele_command_t *post_command); | ||
|
||
static void mod_DEL_func(scene_state_t *ss, exec_state_t *es, | ||
command_state_t *cs, | ||
const tele_command_t *post_command); | ||
|
||
static void op_DEL_CLR_get(const void *data, scene_state_t *ss, | ||
exec_state_t *es, command_state_t *cs); | ||
|
||
static void mod_DEL_X_func(scene_state_t *ss, exec_state_t *es, | ||
command_state_t *cs, | ||
const tele_command_t *post_command); | ||
|
||
static void mod_DEL_R_func(scene_state_t *ss, exec_state_t *es, | ||
command_state_t *cs, | ||
const tele_command_t *post_command); | ||
|
||
const tele_mod_t mod_DEL = MAKE_MOD(DEL, mod_DEL_func, 1); | ||
const tele_op_t op_DEL_CLR = MAKE_GET_OP(DEL.CLR, op_DEL_CLR_get, 0, false); | ||
const tele_mod_t mod_DEL_X = MAKE_MOD(DEL.X, mod_DEL_X_func, 2); | ||
const tele_mod_t mod_DEL_R = MAKE_MOD(DEL.R, mod_DEL_R_func, 2); | ||
|
||
// common code to queue a delay shared between all delay ops | ||
// NOTE it is the responsibility of the callee to call tele_has_delays | ||
static void delay_common_add(scene_state_t *ss, exec_state_t *es, int16_t i, | ||
int16_t delay_time, | ||
const tele_command_t *post_command) { | ||
if (i < DELAY_SIZE) { | ||
ss->delay.count++; | ||
ss->delay.time[i] = delay_time; | ||
ss->delay.origin_script[i] = es_variables(es)->script_number; | ||
ss->delay.origin_i[i] = es_variables(es)->i; | ||
copy_command(&ss->delay.commands[i], post_command); | ||
} | ||
} | ||
|
||
static void mod_DEL_func(scene_state_t *ss, exec_state_t *es, | ||
command_state_t *cs, | ||
const tele_command_t *post_command) { | ||
int16_t i = 0; | ||
int16_t a = cs_pop(cs); | ||
int16_t delay_time = cs_pop(cs); | ||
|
||
if (a < 1) a = 1; | ||
if (delay_time < 1) delay_time = 1; | ||
|
||
// 0 is the magic number for an empty slot. | ||
// Be careful not to set delay.time[i] to 0 before calling this function. | ||
while (ss->delay.time[i] != 0 && i != DELAY_SIZE) i++; | ||
|
||
if (i < DELAY_SIZE) { | ||
ss->delay.count++; | ||
ss->delay.time[i] = a; | ||
ss->delay.origin_script[i] = es_variables(es)->script_number; | ||
ss->delay.origin_i[i] = es_variables(es)->i; | ||
copy_command(&ss->delay.commands[i], post_command); | ||
delay_common_add(ss, es, i, delay_time, post_command); | ||
tele_has_delays(ss->delay.count > 0); | ||
} | ||
} | ||
|
@@ -42,3 +65,67 @@ static void op_DEL_CLR_get(const void *NOTUSED(data), scene_state_t *ss, | |
command_state_t *NOTUSED(cs)) { | ||
clear_delays(ss); | ||
} | ||
|
||
static void mod_DEL_X_func(scene_state_t *ss, exec_state_t *es, | ||
command_state_t *cs, | ||
const tele_command_t *post_command) { | ||
int16_t i = 0; | ||
int16_t num_delays = cs_pop(cs); | ||
int16_t delay_time = cs_pop(cs); | ||
int16_t delay_time_next; | ||
|
||
if (delay_time < 1) delay_time = 1; // minimum delay time = 1ms | ||
|
||
delay_time_next = delay_time; // set first delay time to delay time | ||
|
||
// 0 is the magic number for an empty slot. | ||
// Be careful not to set delay.time[i] to 0 before calling this function. | ||
while (ss->delay.time[i] != 0 && i != DELAY_SIZE) i++; | ||
|
||
while (i < DELAY_SIZE && num_delays > 0) { | ||
// queue the delay | ||
delay_common_add(ss, es, i, delay_time_next, post_command); | ||
|
||
// increment delay time for next delay | ||
// normalise incremented value to stop negative wrap from increment | ||
delay_time_next += delay_time; | ||
delay_time_next = normalise_value(1, 32767, 1, delay_time_next); | ||
|
||
num_delays--; | ||
i++; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, should've looked into the code closer the 1st time.. there is a problem with this spot here. for multiple delays it will find the 1st available slot but for any consecutive delays it will use the next delay without checking if it's free or not. you have to check that for each delay added. this: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wow another good catch. elegant solution too. I'll work on getting that together tonight. |
||
} | ||
|
||
tele_has_delays(ss->delay.count > 0); | ||
} | ||
|
||
static void mod_DEL_R_func(scene_state_t *ss, exec_state_t *es, | ||
command_state_t *cs, | ||
const tele_command_t *post_command) { | ||
int16_t i = 0; | ||
int16_t num_delays = cs_pop(cs); // number of chained delays | ||
int16_t delay_time = cs_pop(cs); // delay time | ||
int16_t delay_time_next; // incremented delay time | ||
|
||
if (delay_time < 1) delay_time = 1; // minimum delay time = 1ms | ||
|
||
delay_time_next = 1; // set first delay time to 1ms to trigger immediately | ||
|
||
// 0 is the magic number for an empty slot. | ||
// Be careful not to set delay.time[i] to 0 before calling this function. | ||
while (ss->delay.time[i] != 0 && i != DELAY_SIZE) i++; | ||
|
||
while (i < DELAY_SIZE && num_delays > 0) { | ||
// queue the delay | ||
delay_common_add(ss, es, i, delay_time_next, post_command); | ||
|
||
// increment delay time for next delay | ||
// normalise incremented value to stop negative wrap from increment | ||
delay_time_next += delay_time; | ||
delay_time_next = normalise_value(1, 32767, 1, delay_time_next); | ||
|
||
num_delays--; | ||
i++; | ||
} | ||
|
||
tele_has_delays(ss->delay.count > 0); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would add a check here to make sure it doesn't exceed
DELAY_SIZE
- imho it's a good idea to have safety checks in helper functions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah good catch I can add that in. on the same topic do you think it would be good to move
tele_has_delays
into the helper function as well? the downside is it would get called excess times times byDEL.X
, but the change would make the helper function slightly more robust for other future usage.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'd leave it out - the function has a well defined and logical contract (it adds a delay),
tele_has_delays
is outside of that (and only has meaning to where this function is called from).