-
Notifications
You must be signed in to change notification settings - Fork 2
/
MISC.C
256 lines (218 loc) · 6.42 KB
/
MISC.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*--misc.c----------------------------------------------------------
* Miscellaneous routines.
*/
#include "main.h"
#include "anim.h"
#define local static
extern BOOL EscFlag;
extern WORD curFrame;
extern BITMAP hidbm, prevFrame;
/* --------------- BugExit, EmergencyExit ---------------
*/
BugExit(char *s)
{
printf("Program Bug: %s.\n", s);
exit(1);
}
EmergencyExit(char *s)
{
printf("%s.\n", s);
exit(1);
}
NotEnoughMemExit()
{
EmergencyExit("Not enough memory to run this program");
}
/* --------------- AbortKeyHit, CheckAbort ---------------
*/
#define ESC 0x1b
local BOOL AbortKeyHit()
{
register WORD i;
while (char_avail()) { /* Consume keys, looking for ESC. */
i = get_char();
if (i == ESC) {
EscFlag = TRUE; /* Remember ESC was hit. */
return TRUE;
}
}
return FALSE; /* Abort key not seen. */
}
/* Once abort key has been hit, further checks see EscFlag. */
BOOL CheckAbort()
{
return (EscFlag || AbortKeyHit());
}
/* --------------- --------------- */
#define bitmap_offs(bm, x, y) (x + (bm)->width * (y))
#define BytesNeeded(pix) EVEN_UP(pix) /* one byte-per-pixel */
/* Must be whole # words. */
/* --------------- BMLineStart ---------------
* Returns a far pointer to the start of line y
* of the given plane in the bitmap.
*/
WORD far *BMLineStart(BITMAP *bm, WORD y, WORD plane)
{
return (WORD_FAR_PTR(bm->seg[plane], bitmap_offs(bm, 0, y)));
}
/* --------------- init_bitmap ---------------
*/
init_bitmap(bm, width, height)
register BITMAP *bm;
WORD width, height;
{
bm->width = BytesNeeded(width);
bm->box.x = 0;
bm->box.y = 0;
bm->box.w = width;
bm->box.h = height;
bm->planes = curDepth;
}
/* --------------- NewBitMap ---------------
* CAUTION: only call when have NOT allocated bm->seg[]'s.
*/
NewBitMap(BITMAP *bm, WORD width, WORD height)
{
init_bitmap(bm, width, height);
bm->seg[0] = DAlloc(N_BYTES_IN_BITMAP);
if (!bm->seg[0])
NotEnoughMemExit();
}
/* --------------- SetBitMap ---------------
*/
void SetBitMap(BITMAP *bm, WORD color)
{
far_setmem(bm->seg[0], 0, N_BYTES_IN_BITMAP, color);
}
/* --------------- FirstAnimFrame ---------------
* Switch to first frame for editing.
*/
/* Read into lpBuffer, but don't transfer to hidbm.
* This gets all the pointers correctly set-up, so that hidbm can
* become the new first frame (by calling AnimSetDirtyBox).
*/
FirstAnimFrame00() {
curFrame = FIRST_FRAME_N;
ReadLpfFrame(curFrame);
}
FirstAnimFrame0() {
/* --- Clear junk from prevFrame. */
far_setmem(BSEG(&prevFrame), 0, N_BYTES_IN_BITMAP, white_color);
FirstAnimFrame00();
PlayDeltaFrame(&hidbm);
}
/* --------------- CopyHidbmToPrevFrame ---------------
*/
local void CopyHidbmToPrevFrame(void) {
far_movmem( BSEG(&hidbm), 0,
BSEG(&prevFrame), 0, N_BYTES_IN_BITMAP );
}
/* --------------- NextAnimFrame0 ---------------
* Switch to next frame for editing.
*/
NextAnimFrame0() {
curFrame++;
if (curFrame > LAST_FRAME_N)
FirstAnimFrame0();
else {
/* (old) current frame is (next) prevFrame.
* Don't use PlayDeltaFrame, because didn't keep Delta in RAM. */
CopyHidbmToPrevFrame();
ReadLpfFrame(curFrame);
PlayDeltaFrame(&hidbm);
/* Convert old current frame to new current frame. */
}
}
/* -------------------------------------------------------------------------
* Disk i/o with critical error detection.
* -------------------------------------------------------------------------
*/
/* returns -1 if it can't read the full number of bytes */
int readfull(int file, char *buffer, unsigned int count) {
return (readdos(file,dataseg(),buffer,count) == count) ? 0: -1;
}
/* returns -1 if it can't read the full number of bytes */
int readdosfull(UWORD file, UWORD seg, UWORD buffer, UWORD count) {
return (readdos(file,seg,buffer,count) == count) ? 0: -1;
}
/* returns -1 if it can't write the full number of bytes */
int writefull(int file, char *buffer, unsigned int count) {
return (writedos(file,dataseg(),buffer,count) == count) ? 0: -1;
}
/* returns -1 if it can't write the full number of bytes */
int writedosfull(UWORD file, UWORD seg, UWORD buffer, UWORD count) {
return (writedos(file,seg,buffer,count) == count) ? 0: -1;
}
long lseekdos(int file, long offset, int origin) {
long result = lseek(file,offset,origin);
return result;
}
/*-----------------------------------------------------------------
* --------------- do_num_to_string -------------------------------
* Convert a number to a string. Parameters:
* UWORD num = # to convert to string.
* char *string = Ptr to string where you want the #.
* UWORD length = # of chars you want in the resulting string. Set to -1
* if you don't require any specific string length. If the string
* is too short, it will be padded with blanks on the left. If it
* is too long, it will be chopped off on the right.
* BOOL negative = Set to TRUE if you want numbers > 32767 to be printed
* as negative (with a leading "-"), or FALSE otherwise.
*/
/* TRUE before calling do_num_to_string, if want padding with 0's
* instead of blanks. Must set back to FALSE when done, so
* other clients will get ' 's.
*/
local BOOL padWithZeroes = FALSE;
void do_num_to_string(UWORD num, char *string, UWORD length, BOOL negative)
{
UWORD temp;
register UWORD index, i;
BOOL start;
index = 0;
/* --- does caller want negative # printed with leading '-'? */
if (negative && num >= 0x8000) {
if (index >= length) goto terminate;
num = -num;
string[index++] = '-';
}
/* --- convert the # to a string */
if (num == 0) {
if (index >= length) goto terminate;
string[index++] = '0';
} else {
start = FALSE;
for (i = 10000; i > 0; i /= 10) {
temp = (num / i);
if (temp || start) {
/* --- if string has reached max length, stop */
if (index >= length) goto terminate;
string[index++] = temp + '0';
start = TRUE;
}
num %= i;
}
}
/* --- terminate the string */
terminate:
string[index] = 0;
/* --- if caller wants string to be at least a certain length, do it */
i = strlen(string);
if ((WORD)i < (WORD)length) {
/* --- string is too short, so add spaces to left */
while ((WORD)i < (WORD)length) {
movmem(string, string + 1, i + 1);
string[0] = (padWithZeroes ? '0' : ' ');
++i;
}
}
}
/* --------------- num_to_string_zeroes ---------------
* Specified length, no negative, padding with zeroes.
*/
void num_to_string_zeroes(UWORD num, char *string, UWORD length) {
padWithZeroes = TRUE;
do_num_to_string(num, string, length, FALSE);
padWithZeroes = FALSE;
}