summaryrefslogtreecommitdiffstats
path: root/src/osd/winui/bitmask.cpp
blob: 062bbc39f0bd3c691859bf96c24803bfd1e273f7 (plain) (blame)
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
// For licensing and usage information, read docs/winui_license.txt
// MASTER
//****************************************************************************
/* bitmask.c - Bitmask support routines - MSH 11/19/1998 */

// standard windows headers
#include <windows.h>

// standard C headers
#include <stdlib.h> /* For malloc and free */

// MAME/MAMEUI headers
#include "bitmask.h"
/* Bit routines */
static UCHAR maskTable[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };

/* Create a new LPBITS struct and return the new structure
 * initialized to 'all bits cleared'
 *
 * nLength is the number of desired bits
 */
LPBITS NewBits(UINT nLength)
{
	UINT nSize = (nLength+7) / 8;

	LPBITS lpBits = (LPBITS)malloc(sizeof(BITS));
	if (lpBits)
	{
		lpBits->m_lpBits = (UCHAR *)malloc(nSize);
		if (lpBits->m_lpBits)
		{
			memset(lpBits->m_lpBits, '\0', nSize);
			lpBits->m_nSize = nSize;
		}
		else
		{
			free(lpBits);
			lpBits = 0;
		}
	}

	return lpBits;
}

void DeleteBits(LPBITS lpBits)
{
	if (!lpBits)
		return;

	if (lpBits->m_nSize && lpBits->m_lpBits)
		free(lpBits->m_lpBits);

	free(lpBits);
}

/* Test the 'nBit'th bit */
BOOL TestBit(LPBITS lpBits, UINT nBit)
{
	UINT offset;
	UCHAR mask;

	if (nBit < 0 || !lpBits || !lpBits->m_lpBits)
		return FALSE;

	offset = nBit >> 3;

	if (offset >= lpBits->m_nSize)
		return FALSE;

	mask = maskTable[nBit & 7];
	return (lpBits->m_lpBits[offset] & mask) ? TRUE : FALSE;
}

/* Set the 'nBit'th bit */
void SetBit(LPBITS lpBits, UINT nBit)
{
	UINT offset;
	UCHAR mask;

	if (nBit < 0 || !lpBits || !lpBits->m_lpBits)
		return;

	offset = nBit >> 3;

	if (offset >= lpBits->m_nSize)
		return;

	mask = maskTable[nBit & 7];
	lpBits->m_lpBits[offset] |= mask;
}

/* Clear the 'nBit'th bit */
void ClearBit(LPBITS lpBits, UINT nBit)
{
	UINT offset;
	UCHAR mask;

	if (nBit < 0 || !lpBits || !lpBits->m_lpBits)
		return;

	offset = nBit >> 3;

	if (offset >= lpBits->m_nSize)
		return;

	mask = maskTable[nBit & 7];
	lpBits->m_lpBits[offset] &= ~mask;
}

/* Set or Clear all bits as specified by 'bSet' */
void SetAllBits(LPBITS lpBits, BOOL bSet)
{
	if (lpBits && lpBits->m_nSize != 0 && lpBits->m_lpBits)
		memset(lpBits->m_lpBits, (!bSet) ? '\0' : '\xFF', lpBits->m_nSize);
}

/* Find next bit that matches 'bSet'
 *
 * 'nStartPos' specifies the bit to start search after
 * 'bSet' specifies to search for a set or unset bit
 *
 * Returns -1 if no bits are found
 */
int FindBit(LPBITS lpBits, int nStartPos, BOOL bSet)
{
	UINT i = 0;

	if (!lpBits || !lpBits->m_nSize || !lpBits->m_lpBits)
		return -1;

	UINT end = lpBits->m_nSize << 3;

	if (nStartPos < 0)
		nStartPos = 0;

	for (i = nStartPos; i < end; i++)
	{
		BOOL res = (TestBit(lpBits, i)) ? TRUE : FALSE;
		if ((res && bSet) || (!res && !bSet))
			return i;
	}

	return -1;
}

/* End of source file */