0
|
1 #include "datum.h"
|
|
2 #include "vis_threading.h"
|
|
3 #include "structs.h"
|
|
4 #include <string.h>
|
|
5
|
|
6 //TODO: Make some kind of "notifier" lock that takes some kind of callback
|
|
7 //to be called when the lock becomes free
|
|
8
|
|
9 typedef struct
|
|
10 {
|
|
11 int offset;
|
|
12 char * buffer;
|
|
13 int size;
|
|
14 VIS_CRITICAL_SECTION(lock)
|
|
15 } fixed_buffer;
|
|
16
|
|
17 int vis_buffer_new(datum ** params, queue_entry * entry)
|
|
18 {
|
|
19 int size = params[0]->c.integers.num_a;
|
|
20 fixed_buffer * buf;
|
|
21 release_ref(params[0]);
|
|
22 params[0] = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer) + size, entry->instance->def->program);
|
|
23 buf = params[0]->c.generic.data;
|
|
24 buf->offset = 0;
|
|
25 buf->buffer = ((char *)buf) + sizeof(fixed_buffer);
|
|
26 buf->size = size;
|
|
27 VIS_InitializeCriticalSection(buf->lock);
|
|
28 return 0;
|
|
29 }
|
|
30
|
|
31 int vis_buffer_lock(datum ** params, queue_entry * entry)
|
|
32 {
|
|
33 fixed_buffer * buf = params[0]->c.generic.data;
|
|
34 VIS_EnterCriticalSection(buf->lock);
|
|
35 return 0;
|
|
36 }
|
|
37
|
|
38 int vis_buffer_unlock(datum ** params, queue_entry * entry)
|
|
39 {
|
|
40 fixed_buffer * buf = params[0]->c.generic.data;
|
|
41 VIS_LeaveCriticalSection(buf->lock);
|
|
42 return 0;
|
|
43 }
|
|
44
|
|
45 int vis_buffer_putbyte(datum ** params, queue_entry * entry)
|
|
46 {
|
|
47 fixed_buffer * buf = params[0]->c.generic.data;
|
|
48 char byte = params[1]->c.integers.num_a;
|
|
49 release_ref(params[1]);
|
|
50 if(buf->offset < buf->size)
|
|
51 {
|
|
52 buf->buffer[buf->offset++] = byte;
|
|
53 params[1] = NULL;
|
|
54 }
|
|
55 else
|
|
56 {
|
|
57 params[1] = params[0];
|
|
58 params[1] = NULL;
|
|
59 }
|
|
60 return 0;
|
|
61 }
|
|
62
|
|
63 int vis_buffer_writebyte(datum ** params, queue_entry * entry)
|
|
64 {
|
|
65 fixed_buffer * buf = params[0]->c.generic.data;
|
|
66 char byte = params[1]->c.integers.num_a;
|
|
67 release_ref(params[1]);
|
|
68 if(buf->offset < buf->size)
|
|
69 {
|
|
70 buf->buffer[buf->offset] = byte;
|
|
71 params[1] = NULL;
|
|
72 }
|
|
73 else
|
|
74 {
|
|
75 params[1] = params[0];
|
|
76 params[1] = NULL;
|
|
77 }
|
|
78 return 0;
|
|
79 }
|
|
80
|
|
81 int vis_buffer_putshort(datum ** params, queue_entry * entry)
|
|
82 {
|
|
83 fixed_buffer * buf = params[0]->c.generic.data;
|
|
84 short * wordbuf;
|
|
85 short word = params[1]->c.integers.num_a;
|
|
86 release_ref(params[1]);
|
|
87 if(buf->offset < buf->size)
|
|
88 {
|
|
89 wordbuf = (short *)buf->buffer;
|
|
90 wordbuf[buf->offset >> 1] = word;
|
|
91 params[1] = NULL;
|
|
92 buf->offset += 2;
|
|
93 }
|
|
94 else
|
|
95 {
|
|
96 params[1] = params[0];
|
|
97 params[1] = NULL;
|
|
98 }
|
|
99 return 0;
|
|
100 }
|
|
101
|
|
102 int vis_buffer_writeshort(datum ** params, queue_entry * entry)
|
|
103 {
|
|
104 fixed_buffer * buf = params[0]->c.generic.data;
|
|
105 short * wordbuf;
|
|
106 short word = params[1]->c.integers.num_a;
|
|
107 release_ref(params[1]);
|
|
108 if(buf->offset < buf->size)
|
|
109 {
|
|
110 wordbuf = (short *)buf->buffer;
|
|
111 wordbuf[buf->offset >> 1] = word;
|
|
112 params[1] = NULL;
|
|
113 }
|
|
114 else
|
|
115 {
|
|
116 params[1] = params[0];
|
|
117 params[1] = NULL;
|
|
118 }
|
|
119 return 0;
|
|
120 }
|
|
121
|
|
122 int vis_buffer_putlong(datum ** params, queue_entry * entry)
|
|
123 {
|
|
124 fixed_buffer * buf = params[0]->c.generic.data;
|
|
125 long * longbuf;
|
|
126 long lword = params[1]->c.integers.num_a;
|
|
127 release_ref(params[1]);
|
|
128 if(buf->offset < buf->size)
|
|
129 {
|
|
130 longbuf = (long *)buf->buffer;
|
|
131 longbuf[buf->offset >> 2] = lword;
|
|
132 params[1] = NULL;
|
|
133 buf->offset += 4;
|
|
134 }
|
|
135 else
|
|
136 {
|
|
137 params[1] = params[0];
|
|
138 params[1] = NULL;
|
|
139 }
|
|
140 return 0;
|
|
141 }
|
|
142
|
|
143 int vis_buffer_writelong(datum ** params, queue_entry * entry)
|
|
144 {
|
|
145 fixed_buffer * buf = params[0]->c.generic.data;
|
|
146 long * longbuf;
|
|
147 long lword = params[1]->c.integers.num_a;
|
|
148 release_ref(params[1]);
|
|
149 if(buf->offset < buf->size)
|
|
150 {
|
|
151 longbuf = (long *)buf->buffer;
|
|
152 longbuf[buf->offset >> 2] = lword;
|
|
153 params[1] = NULL;
|
|
154 }
|
|
155 else
|
|
156 {
|
|
157 params[1] = params[0];
|
|
158 params[1] = NULL;
|
|
159 }
|
|
160 return 0;
|
|
161 }
|
|
162
|
|
163 int vis_buffer_reset(datum ** params, queue_entry * entry)
|
|
164 {
|
|
165 fixed_buffer * buf = params[0]->c.generic.data;
|
|
166 buf->offset = 0;
|
|
167 return 0;
|
|
168 }
|
|
169
|
|
170 #if defined(SEGA) | defined(NINTENDO_DS)
|
|
171 int vis_buffer_fromaddress(datum ** params, queue_entry * entry)
|
|
172 {
|
|
173 char buffer;
|
|
174 datum * out;
|
|
175 int size = params[1]->c.integers.num_a;
|
|
176 fixed_buffer * buf;
|
|
177 release_ref(params[1]);
|
|
178 out = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer), entry->instance->def->program);
|
|
179 buf = out->c.generic.data;
|
|
180 buf->offset = 0;
|
|
181 buf->buffer = (char *)(params[0]->c.integers.num_a);
|
|
182 buf->size = size;
|
|
183 VIS_InitializeCriticalSection(buf->lock);
|
|
184 release_ref(params[0]);
|
|
185 params[0] = out;
|
|
186 return 0;
|
|
187 }
|
|
188 #endif
|
|
189
|
|
190
|