1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 */
19 /*
20 * $Source: r:/prj/lib/src/2d/RCS/chain.c $
21 * $Revision: 1.8 $
22 * $Author: kevin $
23 * $Date: 1994/12/05 21:02:35 $
24 *
25 * Routines for chaining functions to 2D primitives.
26 *
27 * This file is part of the 2D library.
28 *
29 * $Log: chain.c $
30 * Revision 1.8 1994/12/05 21:02:35 kevin
31 * Reworked to avoid linking in unused function tables.
32 *
33 * Revision 1.7 1994/12/02 21:51:39 kevin
34 * Moved chaining globals accessed in gr_set_canvas to grd.c to avoid linking in unused code.
35 *
36 * Revision 1.6 1993/12/07 11:45:15 baf
37 * Renames gr_chain_add_over
38 *
39 * Revision 1.5 1993/12/02 13:44:13 baf
40 * Added the ability to unchain and rechain.
41 *
42 * Revision 1.4 1993/11/30 20:47:08 baf
43 * Chainged generic mode stuff so it can
44 * be done at any time.
45 *
46 * Revision 1.3 1993/11/16 23:06:33 baf
47 * Added the ability to chain void functions
48 * after the primitive.
49 *
50 * Revision 1.2 1993/11/15 03:26:53 baf
51 * Added void chaining (functions that just
52 * get executed and pass on)
53 *
54 * Revision 1.1 1993/11/12 09:29:49 baf
55 * Initial revision
56 *
57 */
58
59 #include "chain.h"
60 #include "chnfuncs.h"
61 #include "grmalloc.h"
62 #include "tabdat.h"
63 #include "bitmap.h"
64 #include "cnvtab.h"
65 #include "cnvdrv.h"
66 #include "icanvas.h"
67 #include "grnull.h"
68
69 grs_func_chain *grd_chain_table[GRD_CANVAS_FUNCS];
70
gr_chain_add_over(int n,void (* f)())71 grs_func_chain *gr_chain_add_over(int n, void (*f)())
72 {
73 grs_func_chain *p = (grs_func_chain *)(malloc(sizeof(grs_func_chain))); // was gr_malloc
74 if (grd_chain_table[n] == NULL) {
75 /* First time: stash and replace primitives */
76 int k;
77 chn_primitives[n] = (void (**)())(malloc(BMT_TYPES*sizeof(void (*)()))); // was gr_malloc
78 for (k=0; k<BMT_TYPES; k++)
79 if (grd_canvas_table_list[k] != NULL)
80 chn_primitives[n][k] = grd_canvas_table_list[k][n];
81 for (k=0; k<BMT_TYPES; k++)
82 if (grd_canvas_table_list[k] != NULL)
83 grd_canvas_table_list[k][n] = chn_canvas_table[n];
84 /* The above two loops are kept apart for a reason:
85 two pointers may be the same, and we want to save the
86 initial values of them all. */
87 }
88 /* Hook into chain */
89 p->f = f;
90 p->next = grd_chain_table[n];
91 p->flags = 0;
92 grd_chain_table[n] = p;
93 return p;
94 }
95
gr_chain_add_before(int n,void (* f)(void))96 grs_func_chain *gr_chain_add_before(int n, void (*f)(void))
97 {
98 grs_func_chain *p;
99 p = gr_chain_add_over(n, f);
100 p->flags |= 1;
101 return p;
102 }
103
gr_chain_add_after(int n,void (* f)(void))104 grs_func_chain *gr_chain_add_after(int n, void (*f)(void))
105 {
106 grs_func_chain *p = (grs_func_chain *)(malloc(sizeof(grs_func_chain))); // was gr_malloc
107 p->f = f;
108 p->next = NULL;
109 p->flags = CHNF_VOID | CHNF_AFTER;
110 if (grd_chain_table[n] == NULL) {
111 /* First time: stash and replace primitives */
112 int k;
113 chn_primitives[n] = (void (**)())(malloc(BMT_TYPES*sizeof(void (*)()))); // was gr_malloc
114 for (k=0; k<BMT_TYPES; k++)
115 if (grd_canvas_table_list[k] != NULL)
116 chn_primitives[n][k] = grd_canvas_table_list[k][n];
117 for (k=0; k<BMT_TYPES; k++)
118 if (grd_canvas_table_list[k] != NULL)
119 grd_canvas_table_list[k][n] = chn_canvas_table[n];
120 /* The above two loops are kept apart for a reason:
121 two pointers may be the same, and we want to save the
122 initial values of them all. */
123 grd_chain_table[n] = p;
124 }
125 else {
126 grs_func_chain *q = grd_chain_table[n];
127 while (q->next != NULL) q = q->next;
128 q->next = p;
129 }
130 return p;
131 }
132
gr_unchain(int n)133 void gr_unchain(int n)
134 {
135 int k;
136 /* check for unchained primitive */
137 if (chn_primitives[n] == NULL) return;
138 for (k=0; k<BMT_TYPES; k++)
139 if (grd_canvas_table_list[k] != NULL)
140 grd_canvas_table_list[k][n] = chn_primitives[n][k];
141 }
142
gr_rechain(int n)143 void gr_rechain(int n)
144 {
145 int k;
146 if (chn_primitives[n] == NULL) return;
147 for (k=0; k<BMT_TYPES; k++)
148 if (grd_canvas_table_list[k] != NULL)
149 grd_canvas_table_list[k][n] = chn_canvas_table[n];
150 }
151
gr_unchain_all()152 void gr_unchain_all()
153 {
154 int k;
155 for (k=0; k<GRD_CANVAS_FUNCS; k++) gr_unchain(k);
156 }
157
gr_rechain_all()158 void gr_rechain_all()
159 {
160 int k;
161 for (k=0; k<GRD_CANVAS_FUNCS; k++) gr_rechain(k);
162 }
163
164
165 /* This returns the next function in the rest of the current chain. */
chain_rest()166 void (*chain_rest())()
167 {
168 for (gr_current_chain = gr_current_chain->next; gr_current_chain != NULL; gr_current_chain = gr_current_chain->next) {
169 if (!(gr_current_chain->flags & CHNF_VOID))
170 return gr_current_chain->f;
171 if (gr_current_chain->flags & CHNF_AFTER) break;
172 gr_current_chain->f();
173 }
174 if (gr_current_primitive <= GET_PIXEL24 || gr_current_primitive >= CALC_ROW)
175 return chn_primitives[gr_current_primitive][grd_pixel_index];
176 return chn_primitives[gr_current_primitive][grd_canvas_index];
177 }
178
179 #include "canvas.h"
180 #include "cnvdat.h"
181 #include "cnvdrv.h"
182 #include "fcntab.h"
183 #include "tabdrv.h"
184 #include "fill.h"
185
gr_force_generic()186 void gr_force_generic()
187 {
188 chn_flags |= CHN_GEN;
189 grd_canvas_table_list[BMT_GEN]=gen_canvas_table;
190 grd_function_table_list[BMT_GEN]= (grt_function_table *) gen_function_table;
191 if (grd_canvas_table != NULL)
192 gr_set_canvas(grd_canvas);
193 }
194
gr_unforce_generic()195 void gr_unforce_generic()
196 {
197 chn_flags &= ~CHN_GEN;
198 gr_set_canvas(grd_canvas);
199 }
200
201