From ade12c314902bc30415cbc97b23d932c6d391884 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Ji=C5=99i=C5=A1t=C4=9B?= Date: Wed, 18 Dec 2024 23:16:30 +0100 Subject: [PATCH] Implement "graphical" way to add mosfets --- inc/FET_sim.h | 11 +++-- src/colors.c | 118 ++++++++++++++++++++++++++++++++++------------ src/schema_mode.c | 80 +++++++++++++++++++++++++++---- src/sim_main.c | 18 ++----- 4 files changed, 172 insertions(+), 55 deletions(-) diff --git a/inc/FET_sim.h b/inc/FET_sim.h index a3f108c..e7215a4 100644 --- a/inc/FET_sim.h +++ b/inc/FET_sim.h @@ -36,10 +36,10 @@ typedef unsigned long t_id; typedef enum e_orientation { - UP, - RIGHT, - DOWN, - LEFT, + UP = 0, + LEFT = 1, + DOWN = 2, + RIGHT = 3, } t_orientation; typedef chtype t_symbol; @@ -146,9 +146,10 @@ int get_input(WINDOW *command_win, t_input *input); const char *state_color_escape(t_state state); void draw_single(WINDOW *command_win, const t_mosfet *mosfet); +void schema_draw_mosfet(WINDOW *schematics_win, const t_mosfet *mosfet); void update_nodes(t_vec *nodes); -int should_open(t_type type, t_state state); +int should_open(const t_mosfet *mosfet); int sim_step(t_vec *nodes, t_vec *mosfets); void setup_terminal(t_windows *windows); diff --git a/src/colors.c b/src/colors.c index 99d9eba..5298d5a 100644 --- a/src/colors.c +++ b/src/colors.c @@ -10,6 +10,13 @@ typedef enum e_nc_color NC_BLUE, } t_nc_color; +typedef struct s_switch_symbol_set +{ + t_symbol open; + t_symbol transition; + t_symbol closed; +} t_switch_symbol_set; + void init_colors(void) { if (!has_colors()) @@ -22,7 +29,7 @@ void init_colors(void) return ; } -t_nc_color get_state_color(t_state state) +static t_nc_color get_state_color(t_state state) { if (state == on || state == pull_up) return (NC_GREEN); @@ -34,6 +41,43 @@ t_nc_color get_state_color(t_state state) return (NC_RED); } +static t_nc_color get_switch_color(const t_mosfet *mosfet) +{ + t_nc_color color; + + if (mosfet->is_opened) + { + if (mosfet->source) + color = get_state_color(mosfet->source->state); + else if (mosfet->drain) + color = get_state_color(mosfet->drain->state); + else + color = NC_RED; + } + else + color = NC_DEFAULT; + return (color); +} + +static t_switch_symbol_set get_switch_set(t_orientation orientation) +{ + t_switch_symbol_set set; + + if (orientation == UP || orientation == DOWN) + { + set.open = ACS_VLINE; + set.transition = '/'; + set.closed = '|'; + } + else + { + set.open = ACS_HLINE; + set.transition = '\\'; + set.closed = '-'; + } + return (set); +} + static void print_in_color(WINDOW *command_win, const char *str, t_nc_color color) { wattron(command_win, COLOR_PAIR(color)); @@ -43,6 +87,49 @@ static void print_in_color(WINDOW *command_win, const char *str, t_nc_color colo return ; } +static void draw_switch(WINDOW *win, const t_mosfet *mosfet, t_orientation orientation) +{ + t_nc_color color; + t_switch_symbol_set set; + t_symbol switch_sym; + + color = get_switch_color(mosfet); + set = get_switch_set(orientation); + if (mosfet->is_opened && should_open(mosfet)) + switch_sym = set.open; + else if ((mosfet->is_opened && !should_open(mosfet)) + || (!mosfet->is_opened && should_open(mosfet))) + switch_sym = set.transition; + else + switch_sym = set.closed; + wattron(win, COLOR_PAIR(color)); + waddch(win, switch_sym); + wattroff(win, COLOR_PAIR(color)); + return ; +} + +void schema_draw_mosfet(WINDOW *schematics_win, const t_mosfet *mosfet) +{ + t_position old_pos; + t_position work_pos; + + getyx(schematics_win, old_pos.y, old_pos.x); + work_pos = mosfet->position; + mvwaddch(schematics_win, work_pos.y, work_pos.x, mosfet->type); + if (mosfet->orientation == UP) + ++work_pos.y; + else if (mosfet->orientation == DOWN) + --work_pos.y; + if (mosfet->orientation == LEFT) + ++work_pos.x; + else if (mosfet->orientation == RIGHT) + --work_pos.x; + wmove(schematics_win, work_pos.y, work_pos.x); + draw_switch(schematics_win, mosfet, mosfet->orientation); + wmove(schematics_win, old_pos.y, old_pos.x); + return ; +} + static void draw_top(WINDOW *command_win, const t_mosfet *mosfet) { if (mosfet->source) @@ -58,33 +145,6 @@ static void draw_top(WINDOW *command_win, const t_mosfet *mosfet) return ; } -static void draw_switch(WINDOW *command_win, const t_mosfet *mosfet) -{ - t_nc_color color; - - if (!mosfet->gate || !mosfet->is_opened) - { - if (mosfet->gate && should_open(mosfet->type, mosfet->gate->state)) - waddch(command_win, '\\'); - else - waddch(command_win, '-'); - } - else if (mosfet->is_opened) - { - if (mosfet->source) - color = get_state_color(mosfet->source->state); - else if (mosfet->drain) - color = get_state_color(mosfet->drain->state); - else - color = NC_RED; - if (should_open(mosfet->type, mosfet->gate->state)) - print_in_color(command_win, "|", color); - else - print_in_color(command_win, "\\", color); - } - return ; -} - static void draw_middle(WINDOW *command_win, const t_mosfet *mosfet) { if (mosfet->gate) @@ -95,7 +155,7 @@ static void draw_middle(WINDOW *command_win, const t_mosfet *mosfet) else print_in_color(command_win, "NULL-", NC_RED); waddch(command_win, mosfet->type); - draw_switch(command_win, mosfet); + draw_switch(command_win, mosfet, LEFT); waddch(command_win, '\n'); return ; } diff --git a/src/schema_mode.c b/src/schema_mode.c index fcddfba..bdb2499 100644 --- a/src/schema_mode.c +++ b/src/schema_mode.c @@ -2,21 +2,85 @@ #include "libft.h" #include +t_position gate_position(const t_mosfet *mosfet) +{ + t_position result; + + result = mosfet->position; + if (mosfet->orientation == UP) + ++result.y; + else if (mosfet->orientation == LEFT) + ++result.x; + else if (mosfet->orientation == DOWN) + --result.y; + else if (mosfet->orientation == RIGHT) + --result.x; + return (result); +} + +void schema_add_mosfet(WINDOW *schematics_win, t_vec *mosfets, t_position pos) +{ + t_mosfet *mosfet; + size_t i; + t_position rel_pos; + int ch; + + i = 0; + while (i < mosfets->size) + { + mosfet = ft_vec_access(mosfets, i); + rel_pos.x = mosfet->position.x - pos.x; + rel_pos.y = mosfet->position.y - pos.y; + if ((-1 <= rel_pos.x && rel_pos.x <= 1) && (-1 <= rel_pos.y && rel_pos.y <= 1)) + { + // Error - mosfets cannot overlap + return ; + } + ++i; + } + mosfet = add_mosfet(mosfets, n, pos, LEFT); + if (!mosfet) + return ; + while (1) + { + schema_draw_mosfet(schematics_win, mosfet); + ch = wgetch(schematics_win); + if (ch == 'r' || ch == 'R') + { + mvwaddch(schematics_win, gate_position(mosfet).y, gate_position(mosfet).x, ' '); + wmove(schematics_win, mosfet->position.y, mosfet->position.x); + } + if (ch == 't' && mosfet->type == p) + mosfet->type = n; + else if (ch == 't' && mosfet->type == n) + mosfet->type = p; + else if (ch == 'r') + mosfet->orientation = (mosfet->orientation + 1) % 4; + else if (ch == 'R') + mosfet->orientation = (mosfet->orientation - 1 + 4) % 4; + else + { + ungetch(ch); + return ; + } + } +} + int handle_key_press(int ch, WINDOW *schematics_win, __attribute__((unused)) t_vec *nodes, __attribute__((unused)) t_vec *mosfets) { - int y; - int x; + t_position pos; - getyx(schematics_win, y, x); + getyx(schematics_win, pos.y, pos.x); if (ch == 'h') - --x; + wmove(schematics_win, pos.y, --pos.x); else if (ch == 'l') - ++x; + wmove(schematics_win, pos.y, ++pos.x); else if (ch == 'j') - ++y; + wmove(schematics_win, ++pos.y, pos.x); else if (ch == 'k') - --y; - wmove(schematics_win, y, x); + wmove(schematics_win, --pos.y, pos.x); + else if (ch == 't') + schema_add_mosfet(schematics_win, mosfets, pos); return (0); } diff --git a/src/sim_main.c b/src/sim_main.c index 19c8253..a161a5e 100644 --- a/src/sim_main.c +++ b/src/sim_main.c @@ -1,21 +1,13 @@ #include "FET_sim.h" #include "libft.h" -int should_open(t_type type, t_state state) -{ - return ((type == p && state == off) || (type == n && state == on)); -} - // Maybe an error should be return when gate is NULL -static void update_mosfet(t_mosfet *mosfet) +int should_open(const t_mosfet *mosfet) { if (!mosfet->gate) - { - mosfet->is_opened = 0; - return ; - } - mosfet->is_opened = should_open(mosfet->type, mosfet->gate->state); - return ; + return (0); + return ((mosfet->type == p && mosfet->gate->state == off) + || (mosfet->type == n && mosfet->gate->state == on)); } static void update_mosfets(t_vec *mosfets) @@ -27,7 +19,7 @@ static void update_mosfets(t_vec *mosfets) while (i < mosfets->size) { mosfet = ft_vec_access(mosfets, i); - update_mosfet(mosfet); + mosfet->is_opened = should_open(mosfet); ++i; } return ; -- 2.30.2