Add some node graphics
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Fri, 20 Dec 2024 17:02:57 +0000 (18:02 +0100)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Fri, 20 Dec 2024 17:02:57 +0000 (18:02 +0100)
When adding MOSFETs in the schema mode, a node is spawned for each of
the terminal. It is also bound and the terminal "position" is used for
its single segment.
I am not satisfied with how the position and symbol of this terminal
segment is obtained, but I cannot think about a more elegant way at this
time.

inc/FET_sim.h
src/build_helper.c
src/colors.c
src/schema_mode.c

index 82356140fcc2165c34016dd7f891d00d992dbbe8..80d150ca02d7c564cf9ba7da14b9ee810bdb9838 100644 (file)
@@ -148,6 +148,7 @@ 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           schema_draw_node(WINDOW *schematics_win, const t_node *node);
 
 void           update_nodes(t_vec *nodes);
 int                    should_open(const t_mosfet *mosfet);
index dc28f925a7db1afe8afcb1fe05f03a173ab670c0..112d18a9811aa61b4423f704efbefb94db3f3a0d 100644 (file)
@@ -15,8 +15,9 @@ int   transfer_mosfet(t_mosfet *mosfet, t_node *from, t_node *to)
 // node 2 should be erased perhaps?
 int    merge_nodes(t_node *node1, t_node *node2)
 {
-       size_t          i;
-       t_mosfet        **mosfet;
+       size_t                  i;
+       t_mosfet                **mosfet;
+       t_node_segment  *seg;
 
        i = 0;
        while (i < node2->connected.size)
@@ -25,6 +26,14 @@ int  merge_nodes(t_node *node1, t_node *node2)
                transfer_mosfet(*mosfet, node2, node1);
                ++i;
        }
+       i = 0;
+       while (i < node2->segments.size)
+       {
+               seg = ft_vec_access(&node2->segments, i);
+               ft_vec_append(&node1->segments, seg);
+               ++i;
+       }
+       ft_vec_forget_range(&node2->segments, node2->segments.size, 0);
        return (0);
 }
 
index 24c1722e68a5825ea0db8aa565f6146cacbdd680..6f6d9453030ebf62f61b0a23208eb0c2d20d3a98 100644 (file)
@@ -130,6 +130,38 @@ void       schema_draw_mosfet(WINDOW *schematics_win, const t_mosfet *mosfet)
        return ;
 }
 
+t_symbol       seg_symbol_to_print(t_symbol seg_symbol)
+{
+       if (seg_symbol == 'd' || seg_symbol == 'u')
+               return (ACS_VLINE);
+       else if (seg_symbol == 'r' || seg_symbol == 'l')
+               return (ACS_HLINE);
+       else
+               return (seg_symbol);
+}
+
+void   schema_draw_node(WINDOW *schematics_win, const t_node *node)
+{
+       const t_node_segment    *seg;
+       size_t                                  i;
+       t_symbol                                symbol;
+
+       wattron(schematics_win, COLOR_PAIR(get_state_color(node->state)));
+       i = 0;
+       while (i < node->segments.size)
+       {
+               seg = ft_vec_caccess(&node->segments, i);
+               symbol = seg_symbol_to_print(seg->symbol);
+               if (symbol != ' ')
+               {
+                       mvwaddch(schematics_win, seg->position.y, seg->position.x, symbol);
+               }
+               ++i;
+       }
+       wattroff(schematics_win, COLOR_PAIR(get_state_color(node->state)));
+       return ;
+}
+
 static void    draw_top(WINDOW *command_win, const t_mosfet *mosfet)
 {
        if (mosfet->source)
@@ -183,10 +215,11 @@ void      draw_single(WINDOW *command_win, const t_mosfet *mosfet)
        return ;
 }
 
-int    refresh_schema_win(WINDOW *schematics_win, __attribute__((unused)) t_vec *nodes, t_vec *mosfets)
+int    refresh_schema_win(WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets)
 {
        size_t                  i;
        const t_mosfet  *mosfet;
+       const t_node    *node;
 
        werase(schematics_win);
        i = 0;
@@ -196,6 +229,13 @@ int        refresh_schema_win(WINDOW *schematics_win, __attribute__((unused)) t_vec *no
                schema_draw_mosfet(schematics_win, mosfet);
                ++i;
        }
+       i = 0;
+       while (i < nodes->size)
+       {
+               node = ft_vec_caccess(nodes, i);
+               schema_draw_node(schematics_win, node);
+               ++i;
+       }
        wrefresh(schematics_win);
        return (1);
 }
index bdb2499fa871e787f1e9d447ac9d9a8398c13c15..fd0626c6cd9f10b07bac479171d2e9251f3a266e 100644 (file)
@@ -2,11 +2,12 @@
 #include "libft.h"
 #include <ncurses.h>
 
-t_position     gate_position(const t_mosfet *mosfet)
+t_position     mosfet_channel_rel_pos(const t_mosfet *mosfet)
 {
        t_position      result;
 
-       result = mosfet->position;
+       result.x = 0;
+       result.y = 0;
        if (mosfet->orientation == UP)
                ++result.y;
        else if (mosfet->orientation == LEFT)
@@ -18,11 +19,113 @@ t_position gate_position(const t_mosfet *mosfet)
        return (result);
 }
 
-void   schema_add_mosfet(WINDOW *schematics_win, t_vec *mosfets, t_position pos)
+t_position     mosfet_up_rel_pos(const t_mosfet *mosfet)
+{
+       t_position      result;
+
+       result.x = 0;
+       result.y = 0;
+       if (mosfet->orientation == UP)
+               ++result.x;
+       else if (mosfet->orientation == LEFT)
+               --result.y;
+       else if (mosfet->orientation == DOWN)
+               --result.x;
+       else if (mosfet->orientation == RIGHT)
+               ++result.y;
+       return (result);
+}
+
+static t_position      pos_add(t_position pos1, t_position pos2)
+{
+       t_position      res;
+
+       res.x = pos1.x + pos2.x;
+       res.y = pos1.y + pos2.y;
+       return (res);
+}
+
+static t_position      pos_sub(t_position pos1, t_position pos2)
+{
+       t_position      res;
+
+       res.x = pos1.x - pos2.x;
+       res.y = pos1.y - pos2.y;
+       return (res);
+}
+
+void   add_terminal_segment(t_node *node, t_mosfet *mosfet, t_terminal term)
+{
+       t_node_segment  segment;
+
+       segment.position = (t_position){.x = 0, .y = 0};
+       if (term == source)
+       {
+               segment.position = pos_add(mosfet_channel_rel_pos(mosfet), mosfet_up_rel_pos(mosfet));
+               if (mosfet->orientation == LEFT)
+                       segment.symbol = 'd';
+               else if (mosfet->orientation == DOWN)
+                       segment.symbol = 'r';
+               else if (mosfet->orientation == RIGHT)
+                       segment.symbol = 'u';
+               else if (mosfet->orientation == UP)
+                       segment.symbol = 'l';
+       }
+       else if (term == drain)
+       {
+               segment.position = pos_sub(mosfet_channel_rel_pos(mosfet), mosfet_up_rel_pos(mosfet));
+               if (mosfet->orientation == LEFT)
+                       segment.symbol = 'u';
+               else if (mosfet->orientation == DOWN)
+                       segment.symbol = 'l';
+               else if (mosfet->orientation == RIGHT)
+                       segment.symbol = 'd';
+               else if (mosfet->orientation == UP)
+                       segment.symbol = 'r';
+       }
+       else if (term == gate)
+       {
+               segment.position = pos_sub(segment.position, mosfet_channel_rel_pos(mosfet));
+               if (mosfet->orientation == LEFT)
+                       segment.symbol = 'r';
+               else if (mosfet->orientation == DOWN)
+                       segment.symbol = 'u';
+               else if (mosfet->orientation == RIGHT)
+                       segment.symbol = 'l';
+               else if (mosfet->orientation == UP)
+                       segment.symbol = 'd';
+       }
+       segment.position = pos_add(segment.position, mosfet->position);
+       ft_vec_append(&node->segments, &segment);
+       return ;
+}
+
+
+void   add_terminal_nodes(WINDOW *schematics_win, t_vec *nodes, t_mosfet *mosfet)
+{
+       t_node  *node;
+
+       node = add_node(nodes, floating);
+       bind_fet_node(mosfet, node, source);
+       node = add_node(nodes, floating);
+       bind_fet_node(mosfet, node, gate);
+       node = add_node(nodes, floating);
+       bind_fet_node(mosfet, node, drain);
+       add_terminal_segment(mosfet->source, mosfet, source);
+       add_terminal_segment(mosfet->gate, mosfet, gate);
+       add_terminal_segment(mosfet->drain, mosfet, drain);
+       schema_draw_node(schematics_win, mosfet->source);
+       schema_draw_node(schematics_win, mosfet->gate);
+       schema_draw_node(schematics_win, mosfet->drain);
+       return ;
+}
+
+void   schema_add_mosfet(WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets, t_position pos)
 {
        t_mosfet        *mosfet;
        size_t          i;
        t_position      rel_pos;
+       t_position      gate_pos;
        int                     ch;
 
        i = 0;
@@ -47,7 +150,8 @@ void schema_add_mosfet(WINDOW *schematics_win, t_vec *mosfets, t_position pos)
                ch = wgetch(schematics_win);
                if (ch == 'r' || ch == 'R')
                {
-                       mvwaddch(schematics_win, gate_position(mosfet).y, gate_position(mosfet).x, ' ');
+                       gate_pos = pos_add(mosfet->position, mosfet_channel_rel_pos(mosfet));
+                       mvwaddch(schematics_win, gate_pos.y, gate_pos.x, ' ');
                        wmove(schematics_win, mosfet->position.y, mosfet->position.x);
                }
                if (ch == 't' && mosfet->type == p)
@@ -60,13 +164,15 @@ void       schema_add_mosfet(WINDOW *schematics_win, t_vec *mosfets, t_position pos)
                        mosfet->orientation = (mosfet->orientation - 1 + 4) % 4;
                else
                {
+                       add_terminal_nodes(schematics_win, nodes, mosfet);
+                       wmove(schematics_win, mosfet->position.y, mosfet->position.x);
                        ungetch(ch);
                        return ;
                }
        }
 }
 
-int    handle_key_press(int ch, WINDOW *schematics_win, __attribute__((unused)) t_vec *nodes, __attribute__((unused)) t_vec *mosfets)
+int    handle_key_press(int ch, WINDOW *schematics_win, t_vec *nodes, t_vec *mosfets)
 {
        t_position      pos;
 
@@ -80,7 +186,7 @@ int  handle_key_press(int ch, WINDOW *schematics_win, __attribute__((unused)) t_v
        else if (ch == 'k')
                wmove(schematics_win, --pos.y, pos.x);
        else if (ch == 't')
-               schema_add_mosfet(schematics_win, mosfets, pos);
+               schema_add_mosfet(schematics_win, nodes, mosfets, pos);
        return (0);
 }