Implement "graphical" way to add mosfets
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Wed, 18 Dec 2024 22:16:30 +0000 (23:16 +0100)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Wed, 18 Dec 2024 22:16:30 +0000 (23:16 +0100)
inc/FET_sim.h
src/colors.c
src/schema_mode.c
src/sim_main.c

index a3f108cc93676668279fa61ce97d068ada9af750..e7215a4c254a72254cb47a40b379c4d2db2393d1 100644 (file)
@@ -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);
index 99d9ebab9c1b09e99b3b49dbccfa29cc035dd00c..5298d5a195518ad7c59f77ddd8e1e78f7fbaa976 100644 (file)
@@ -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 ;
 }
index fcddfbaef4583e0a88c1e90039887c6f9df0e46d..bdb2499fa871e787f1e9d447ac9d9a8398c13c15 100644 (file)
@@ -2,21 +2,85 @@
 #include "libft.h"
 #include <ncurses.h>
 
+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);
 }
 
index 19c825388a9c40fd39e5d145c25a23bc5def4b2b..a161a5ec631258eef644eac209b80808be16cd7a 100644 (file)
@@ -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 ;