e7eabd46b9
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1545 8092fc87-c524-0410-9efc-e669fe64eaf9
256 lines
6.4 KiB
C++
256 lines
6.4 KiB
C++
/*--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;
|
|
}
|