Skip to content
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

Create Orgasm Modes: Denial_count and Milk-o-matic #79

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ and is automatically generated. Here is a quick summary of config variables:
|`sensor_sensitivity`|Byte|128|Analog pressure prescaling. Please see instruction manual.|
|`use_average_values`|Boolean|false|Use average values when calculating arousal. This smooths noisy data.|
|`vibration_mode`|VibrationMode|RampStop|Vibration Mode for main vibrator control.|
|`use_post_orgasm`|Boolean|false|Use post-orgasm torture mode and functionality.|
|`use_orgasm_modes`|Boolean|false|Use orgasm and post-orgasm torture modes and functionality.|
|`clench_pressure_sensitivity`|Int|200|Minimum additional Arousal level to detect clench. See manual.|
|`clench_time_to_orgasm_ms`|Int|1500|Threshold variable that is milliseconds count of clench to detect orgasm. See manual.|
|`clench_detector_in_edging`|Boolean|false|Use the clench detector to adjust Arousal. See manual.|
Expand All @@ -59,6 +59,11 @@ and is automatically generated. Here is a quick summary of config variables:
|`post_orgasm_menu_lock`|Boolean|false|Deny access to menu starting after orgasm detected.|
|`max_clench_duration_ms`|Int|3000|Duration the clench detector can raise arousal if clench detector turned on in edging session.|
|`clench_time_threshold_ms`|Int|900|Threshold variable that is milliseconds counts to detect the start of clench.|
|`denials_count_to_orgasm`|Int|10|How many denials before permiting an orgasm, if this mode is chosen.|
|`milk_o_matic_rest_duration_seconds`|Int|60|How long to rest before restarting an other round of Denial_count edging.|
|`random_orgasm_triggers`|Boolean|false|Randomize Edge timer and Denial count to minimum of 1/2 of their values.|
|`to_orgasm_mode`|OrgasmMode|Timer|Timer, Denial_count and Milk-O-Matic. Random is a choice between Timer and Milk-o-matic. See documentation for more details.|
|`max_orgasms`|Int|4|Milk-o-matic maximum orgasms before turning off.|


\* AzureFang refers to a common wireless technology that is blue and involves chewing face-rocks. However, the
Expand All @@ -77,6 +82,14 @@ and is automatically generated. Here is a quick summary of config variables:
|3|Enhancement|Vibrator speed ramps up as arousal increases, holding a peak for ramp_time.|
|0|Global Sync|When set on secondary vibrators, they will follow the primary vibrator speed.|

### Orgasm Modes:
|ID|Name|Description|
|---|---|---|
|0|Denial_count|How many Denials before permiting an orgasm. Value set with - "Denials to permit orgasm" in the Orgasm Menu|
|1|Timer|How long to edge before permiting an orgasm. Value set with - "Edge Duration Minutes" in the Orgasm Menu|
|2|Milk_o_matic|Cycles in Denial_count mode after each orgasm. Repeats until max_orgasms reached|
|3|Random_mode|Random choice Timer or milk-o-matic before orgasm. For best result choose "Edge Duration Minutes" = 60 min and "Denials to permit orgasm" = 20. the idea is not knowing if you will have an 1 hours tease or multiple orgasm within that same 1 hour. Max_orgasms stops the session after it's reached.|

### post_orgasm_duration_seconds:
|Seconds|Description|
|---|---|
Expand Down
7 changes: 6 additions & 1 deletion include/assets/config_help.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ extern "C" {
#define SENSOR_SENSITIVITY_HELP _HELPSTR("Analog pressure prescaling. Please see instruction manual.")
#define USE_AVERAGE_VALUES_HELP _HELPSTR("Use average values when calculating arousal. This smooths noisy data.")
#define VIBRATION_MODE_HELP _HELPSTR("Vibration Mode for main vibrator control.")
#define USE_POST_ORGASM_HELP _HELPSTR("Use post-orgasm torture mode and functionality.")
#define USE_ORGASM_MODES_HELP _HELPSTR("Use orgasm and post-orgasm torture modes and functionality.")
#define CLENCH_PRESSURE_SENSITIVITY_HELP _HELPSTR("Minimum additional Arousal level to detect clench. See manual.")
#define CLENCH_TIME_TO_ORGASM_MS_HELP _HELPSTR("Threshold variable that is milliseconds count of clench to detect orgasm. See manual.")
#define CLENCH_DETECTOR_IN_EDGING_HELP _HELPSTR("Use the clench detector to adjust Arousal. See manual.")
Expand All @@ -57,6 +57,11 @@ extern "C" {
#define POST_ORGASM_MENU_LOCK_HELP _HELPSTR("Deny access to menu starting after orgasm detected.")
#define MAX_CLENCH_DURATION_MS_HELP _HELPSTR("Duration the clench detector can raise arousal if clench detector turned on in edging session.")
#define CLENCH_TIME_THRESHOLD_MS_HELP _HELPSTR("Threshold variable that is milliseconds counts to detect the start of clench.")
#define DENIALS_COUNT_TO_ORGASM_HELP _HELPSTR("How many denials before permiting an orgasm, if this mode is chosen.")
#define MILK_O_MATIC_REST_DURATION_SECONDS_HELP _HELPSTR("How long to rest before restarting an other round of Denial_count edging.")
#define RANDOM_ORGASM_TRIGGERS_HELP _HELPSTR("Randomize Edge timer and Denial count to minimum of 1/2 of their values.")
#define TO_ORGASM_MODE_HELP _HELPSTR("Timer, Denial_count and Milk-O-Matic. Random is a choice between Timer and Milk-o-matic. See documentation for more details.")
#define MAX_ORGASMS_HELP _HELPSTR("Milk-o-matic maximum orgasms before turning off.")

#ifdef __cplusplus
}
Expand Down
26 changes: 24 additions & 2 deletions include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ enum vibration_mode { RampStop = 1, Depletion = 2, Enhancement = 3, Pattern = 4,

typedef enum vibration_mode vibration_mode_t;

// To orgasm Modes
// See vibration_mode_controller.h for more.

enum to_orgasm_mode { Denial_count = 0, Timer = 1, Milk_o_matic = 2, Random_mode = 3 };

typedef enum to_orgasm_mode to_orgasm_mode_t;

/**
* Main Configuration Struct!
*
Expand Down Expand Up @@ -129,8 +136,8 @@ struct config {

//= Post orgasm torure stuff

// Use post-orgasm torture mode and functionality.
bool use_post_orgasm;
// Use orgasm and post-orgasm torture mode and functionality.
bool use_orgasm_modes;
// Threshold over arousal to detect a clench : Lower values increase sensitivity
int clench_pressure_sensitivity;
// Duration the clench detector can raise arousal if clench detector turned on in edging session
Expand All @@ -149,6 +156,21 @@ struct config {
bool edge_menu_lock;
// Deny access to menu starting after orgasm detected
bool post_orgasm_menu_lock;
// Edging needed to permit orgasm (Max value if ramdom selected).
int denials_count_to_orgasm;
// milk_o_matic rest period in seconds before restart edge+orgasm
int milk_o_matic_rest_duration_seconds;
// random timer and denial_count to orgasm from set values. minimum is 1/2
bool random_orgasm_triggers;
// how many orgasms before stopping in milk-o-matic
int max_orgasms;


// Timer : default original mode
// Edge_count will permit orgasm after # denial reached
// Milk-O-Matic will restart edge+orgasm indefenetly and randomly choose Timer or edge_count at each loop
// Random choose Timer or Edge_count at start of session
int to_orgasm_mode;

//= Internal System Configuration (Update only if you know what you're doing)

Expand Down
7 changes: 6 additions & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,17 @@ CONFIG_DEFS {
CFG_NUMBER(update_frequency_hz, 50);
CFG_NUMBER(sensor_sensitivity, 128);
CFG_BOOL(use_average_values, false);
CFG_NUMBER(denials_count_to_orgasm, 10);
CFG_NUMBER(milk_o_matic_rest_duration_seconds, 60);
CFG_ENUM(to_orgasm_mode, to_orgasm_mode_t, Timer);
CFG_BOOL(random_orgasm_triggers, false);
CFG_NUMBER(max_orgasms, 4);

// Vibration Settings
CFG_ENUM(vibration_mode, vibration_mode_t, RampStop);

// Post-Orgasm Torture
CFG_BOOL(use_post_orgasm, false);
CFG_BOOL(use_orgasm_modes, false);
CFG_NUMBER(clench_pressure_sensitivity, 200);
CFG_NUMBER(clench_time_to_orgasm_ms, 1500);
CFG_NUMBER(clench_time_threshold_ms, 900);
Expand Down
83 changes: 79 additions & 4 deletions src/menus/orgasm_settings_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,46 @@

void on_config_save(int value, int final, UI_INPUT_ARG_TYPE arg);

void on_to_orgasm_select(const ui_input_select_option_t* option, int final, UI_INPUT_ARG_TYPE arg) {
to_orgasm_mode_t mode = (to_orgasm_mode_t)option->ival;
if (final) Config.to_orgasm_mode = mode;
on_config_save(mode, final, arg);
}

static const ui_input_select_option_t to_orgasm_modes[] = {
{
.label = "Timer",
.ival = Timer,
.value = NULL,
},
{
.label = "Denial count",
.ival = Denial_count,
.value = NULL,
},
{
.label = "Random choice",
.ival = Random_mode,
.value = NULL,
},
{
.label = "Milk-O-Matic",
.ival = Milk_o_matic,
.value = NULL,
},
};

static const ui_input_select_t TO_ORGASM_MODE_INPUT = {
SelectInputValues(
"Orgasm Modes",
&Config.to_orgasm_mode,
&to_orgasm_modes,
sizeof(to_orgasm_modes) / sizeof(to_orgasm_modes[0]),
on_to_orgasm_select
),
.input.help = TO_ORGASM_MODE_HELP,
};

static const ui_input_numeric_t EDGING_DURATION_INPUT = {
UnsignedInputValues(
"Edge Duration Minutes", &Config.auto_edging_duration_minutes, UNIT_MINUTES, on_config_save
Expand All @@ -31,9 +71,9 @@ static const ui_input_numeric_t POST_ORGASM_DURATION_SECONDS_INPUT = {
.input.help = POST_ORGASM_DURATION_SECONDS_HELP
};

static const ui_input_toggle_t USE_POST_ORGASM_INPUT = {
ToggleInputValues("Use Post Orgasm Mode", &Config.use_post_orgasm, on_config_save),
.input.help = USE_POST_ORGASM_HELP
static const ui_input_toggle_t USE_ORGASM_MODES_INPUT = {
ToggleInputValues("Enable Orgasm Modes", &Config.use_orgasm_modes, on_config_save),
.input.help = USE_ORGASM_MODES_HELP
};

static const ui_input_toggle_t EDGE_MENU_LOCK_INPUT = {
Expand All @@ -59,15 +99,50 @@ static const ui_input_numeric_t CLENCH_PRESSURE_SENSITIVITY_INPUT = {
.input.help = CLENCH_PRESSURE_SENSITIVITY_HELP
};

static const ui_input_numeric_t DENIALS_COUNT_TO_ORGASM_INPUT = {
UnsignedInputValues("Denials to permit orgasm", &Config.denials_count_to_orgasm, "", on_config_save),
.max = 255,
.step = 1,
.input.help = DENIALS_COUNT_TO_ORGASM_HELP
};

static const ui_input_numeric_t MILK_O_MATIC_REST_DURATION_INPUT = {
UnsignedInputValues(
"Milk-o-matic resting duration", &Config.milk_o_matic_rest_duration_seconds, UNIT_SECONDS, on_config_save
),
.max = 1800,
.step = 1,
.input.help = MILK_O_MATIC_REST_DURATION_SECONDS_HELP
};

static const ui_input_toggle_t RANDOM_ORGASM_TRIGGERS_INPUT = {
ToggleInputValues("Random Timer and Edge_count", &Config.random_orgasm_triggers, on_config_save),
.input.help = RANDOM_ORGASM_TRIGGERS_HELP
};

static const ui_input_numeric_t MAX_ORGASMS_INPUT = {
UnsignedInputValues(
"Milk-o-matic max orgasms", &Config.max_orgasms, "", on_config_save
),
.max = 255,
.step = 1,
.input.help = MAX_ORGASMS_HELP
};

static void on_open(const ui_menu_t* m, UI_MENU_ARG_TYPE arg) {
ui_menu_add_input(m, (ui_input_t*)&USE_ORGASM_MODES_INPUT);
ui_menu_add_input(m, (ui_input_t*)&TO_ORGASM_MODE_INPUT);
ui_menu_add_input(m, (ui_input_t*)&DENIALS_COUNT_TO_ORGASM_INPUT);
ui_menu_add_input(m, (ui_input_t*)&EDGING_DURATION_INPUT);
ui_menu_add_input(m, (ui_input_t*)&CLENCH_TIME_TO_ORGASM_MS_INPUT);
ui_menu_add_input(m, (ui_input_t*)&USE_POST_ORGASM_INPUT);
ui_menu_add_input(m, (ui_input_t*)&POST_ORGASM_DURATION_SECONDS_INPUT);
ui_menu_add_input(m, (ui_input_t*)&EDGE_MENU_LOCK_INPUT);
ui_menu_add_input(m, (ui_input_t*)&POST_ORGASM_MENU_LOCK_INPUT);
ui_menu_add_input(m, (ui_input_t*)&CLENCH_DETECTOR_IN_EDGING_INPUT);
ui_menu_add_input(m, (ui_input_t*)&CLENCH_PRESSURE_SENSITIVITY_INPUT);
ui_menu_add_input(m, (ui_input_t*)&MILK_O_MATIC_REST_DURATION_INPUT);
ui_menu_add_input(m, (ui_input_t*)&MAX_ORGASMS_INPUT);
ui_menu_add_input(m, (ui_input_t*)&RANDOM_ORGASM_TRIGGERS_INPUT);
}

DYNAMIC_MENU(ORGASM_SETTINGS_MENU, "Orgasm Settings", on_open);
87 changes: 80 additions & 7 deletions src/orgasm_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ static struct {
oc_bool_t menu_is_locked;
oc_bool_t detected_orgasm;
int post_orgasm_duration_seconds;
uint8_t edge_count_to_orgasm;
to_orgasm_mode_t to_orgasm_mode;
uint8_t auto_edging_duration_minutes;
bool random_orgasm_triggers;
uint8_t orgasm_count;
} post_orgasm_state;

#define update_check(variable, value) \
Expand Down Expand Up @@ -98,7 +103,9 @@ void orgasm_control_init(void) {
output_state.vibration_mode = Config.vibration_mode;
output_state.edge_time_out = 10000;
post_orgasm_state.clench_pressure_threshold = 4096;

post_orgasm_state.edge_count_to_orgasm = Config.denials_count_to_orgasm;
post_orgasm_state.to_orgasm_mode = Config.to_orgasm_mode;
post_orgasm_state.orgasm_count = 0;
running_average_init(&arousal_state.average, Config.pressure_smoothing);
}

Expand Down Expand Up @@ -171,9 +178,11 @@ static void orgasm_control_updateArousal() {

// Orgasm detected
if (post_orgasm_state.clench_duration_millis >= Config.clench_time_to_orgasm_ms &&
orgasm_control_isPermitOrgasmReached()) {
orgasm_control_isPermitOrgasmReached() &&
post_orgasm_state.detected_orgasm == ocFALSE) {
post_orgasm_state.detected_orgasm = ocTRUE;
post_orgasm_state.clench_duration = 0;
post_orgasm_state.orgasm_count += 1;
}

// ajust arousal if Clench_detector in Edge is turned on
Expand Down Expand Up @@ -290,13 +299,37 @@ static void orgasm_control_updateEdgingTime() { // Edging+Orgasm timer
if (output_state.output_mode == OC_MANUAL_CONTROL) {
post_orgasm_state.menu_is_locked = ocFALSE;
post_orgasm_state.post_orgasm_duration_seconds = Config.post_orgasm_duration_seconds;
post_orgasm_state.detected_orgasm = ocFALSE;
post_orgasm_state.to_orgasm_mode = Config.to_orgasm_mode;
post_orgasm_state.random_orgasm_triggers = Config.random_orgasm_triggers;
return;
}

// keep edging start time to current time as long as system is not in Edge-Orgasm mode 2
if (output_state.output_mode != OC_ORGASM_MODE) {
post_orgasm_state.auto_edging_start_millis = (esp_timer_get_time() / 1000UL);
post_orgasm_state.post_orgasm_start_millis = 0;
post_orgasm_state.orgasm_count = 0;

if ( post_orgasm_state.to_orgasm_mode == Random_mode ) {
post_orgasm_state.to_orgasm_mode = (random() % 2 + 1);
}
post_orgasm_state.edge_count_to_orgasm = arousal_state.denial_count + Config.denials_count_to_orgasm;
post_orgasm_state.auto_edging_duration_minutes = Config.auto_edging_duration_minutes;
} else {
// Orgasm mode started
// Randomize timer and denial_count to orgasm.
if (post_orgasm_state.random_orgasm_triggers) {
// Only run once afer start of session
post_orgasm_state.random_orgasm_triggers = false ;
int min_count = round( Config.denials_count_to_orgasm / 2 );
int min_edge_time = round( Config.auto_edging_duration_minutes / 2 );

post_orgasm_state.edge_count_to_orgasm = arousal_state.denial_count +
min_count + rand() % (Config.denials_count_to_orgasm - min_count);
post_orgasm_state.auto_edging_duration_minutes =
min_edge_time + rand() % (Config.auto_edging_duration_minutes - min_edge_time );
}
}

// Lock Menu if turned on. and in Edging_orgasm mode
Expand Down Expand Up @@ -349,7 +382,35 @@ static void orgasm_control_updateEdgingTime() { // Edging+Orgasm timer
} else { // Post_orgasm timer reached
if (output_state.motor_speed > 0) { // Ramp down motor speed to 0
output_state.motor_speed = output_state.motor_speed - 1;
} else {
} else if ( (post_orgasm_state.to_orgasm_mode == Milk_o_matic) &&
(post_orgasm_state.orgasm_count < Config.max_orgasms)) {
// The motor has been turnned off but this is Milk-O-Matic orgasm mode. Prepare for next round.
output_state.motor_speed = 0;
eom_hal_set_encoder_rgb(255, 0, 127);

// now give a break before restarting edging
if (esp_timer_get_time() / 1000UL > post_orgasm_state.post_orgasm_start_millis +
post_orgasm_state.post_orgasm_duration_millis +
(Config.milk_o_matic_rest_duration_seconds * 1000))
{
// Rest period is finished. Reset variables for next round
post_orgasm_state.auto_edging_start_millis = (esp_timer_get_time() / 1000UL);
post_orgasm_state.post_orgasm_start_millis = 0;
post_orgasm_state.to_orgasm_mode = Denial_count;
post_orgasm_state.detected_orgasm = ocFALSE;
post_orgasm_state.menu_is_locked = ocFALSE;

// Set the new denial count limit to reach before next orgasm
// Randomize denial_count if turned on
if (Config.random_orgasm_triggers) {
// re-enable calculation of random for next round
post_orgasm_state.random_orgasm_triggers = true;
} else {
post_orgasm_state.edge_count_to_orgasm = arousal_state.denial_count + Config.denials_count_to_orgasm;
}
orgasm_control_resumeControl();
}
} else { // This is a normmal edge+orgasm session, turn everything off
post_orgasm_state.menu_is_locked = ocFALSE;
post_orgasm_state.detected_orgasm = ocFALSE;
output_state.motor_speed = 0;
Expand Down Expand Up @@ -607,13 +668,25 @@ void orgasm_control_permitOrgasmNow(int seconds) {
}

oc_bool_t orgasm_control_isPermitOrgasmReached() {
// Detect if edging time has passed
if ((esp_timer_get_time() / 1000UL) > (post_orgasm_state.auto_edging_start_millis +
(Config.auto_edging_duration_minutes * 60 * 1000))) {
return ocTRUE;
if (post_orgasm_state.to_orgasm_mode == Timer ){
// Detect if edging time has passed
if ((esp_timer_get_time() / 1000UL) > (post_orgasm_state.auto_edging_start_millis +
(post_orgasm_state.auto_edging_duration_minutes * 60 * 1000))) {
return ocTRUE;
} else {
return ocFALSE;
}
} else if (post_orgasm_state.to_orgasm_mode == Denial_count ||
post_orgasm_state.to_orgasm_mode == Milk_o_matic) {
if (arousal_state.denial_count >= post_orgasm_state.edge_count_to_orgasm) {
return ocTRUE;
} else {
return ocFALSE;
}
} else {
return ocFALSE;
}

}

oc_bool_t orgasm_control_isPostOrgasmReached() {
Expand Down
4 changes: 2 additions & 2 deletions src/pages/edging_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static void _draw_buttons(u8g2_t* d, orgasm_output_mode_t mode) {
} else if (mode == OC_MANUAL_CONTROL) {
ui_draw_button_labels(d, btn1, btn2, _("AUTO"));
} else if (mode == OC_AUTOMAITC_CONTROL) {
if (Config.use_post_orgasm == true) {
if (Config.use_orgasm_modes == true) {
ui_draw_button_labels(d, btn1, btn2, _("POST"));
} else {
ui_draw_button_labels(d, btn1, btn2, _("MANUAL"));
Expand Down Expand Up @@ -292,7 +292,7 @@ on_button(eom_hal_button_t button, eom_hal_button_event_t event, void* arg) {
if (mode == OC_MANUAL_CONTROL) {
orgasm_control_set_output_mode(OC_AUTOMAITC_CONTROL);
} else if (mode == OC_AUTOMAITC_CONTROL) {
if (Config.use_post_orgasm == true) {
if (Config.use_orgasm_modes == true) {
orgasm_control_set_output_mode(OC_ORGASM_MODE);
} else {
orgasm_control_set_output_mode(OC_MANUAL_CONTROL);
Expand Down
Loading