xref: /haiku/src/add-ons/accelerants/ati/mach64_cursor.cpp (revision 80829ec813241c9a702a45e39929286f13c55093)
1*80829ec8SRene Gollent /*
2*80829ec8SRene Gollent 	Copyright 2009 Haiku, Inc.  All rights reserved.
3*80829ec8SRene Gollent 	Distributed under the terms of the MIT license.
4*80829ec8SRene Gollent 
5*80829ec8SRene Gollent 	Authors:
6*80829ec8SRene Gollent 	Gerald Zajac 2009
7*80829ec8SRene Gollent */
8*80829ec8SRene Gollent 
9*80829ec8SRene Gollent 
10*80829ec8SRene Gollent #include "accelerant.h"
11*80829ec8SRene Gollent #include "mach64.h"
12*80829ec8SRene Gollent 
13*80829ec8SRene Gollent #include <string.h>
14*80829ec8SRene Gollent 
15*80829ec8SRene Gollent 
16*80829ec8SRene Gollent 
17*80829ec8SRene Gollent void
Mach64_ShowCursor(bool bShow)18*80829ec8SRene Gollent Mach64_ShowCursor(bool bShow)
19*80829ec8SRene Gollent {
20*80829ec8SRene Gollent 	// Turn cursor on/off.
21*80829ec8SRene Gollent 
22*80829ec8SRene Gollent    	OUTREGM(GEN_TEST_CNTL, bShow ? HWCURSOR_ENABLE : 0, HWCURSOR_ENABLE);
23*80829ec8SRene Gollent }
24*80829ec8SRene Gollent 
25*80829ec8SRene Gollent 
26*80829ec8SRene Gollent void
Mach64_SetCursorPosition(int x,int y)27*80829ec8SRene Gollent Mach64_SetCursorPosition(int x, int y)
28*80829ec8SRene Gollent {
29*80829ec8SRene Gollent 	SharedInfo& si = *gInfo.sharedInfo;
30*80829ec8SRene Gollent 
31*80829ec8SRene Gollent 	// xOffset & yOffset are used for displaying partial cursors on screen edges.
32*80829ec8SRene Gollent 
33*80829ec8SRene Gollent 	uint8 xOffset = 0;
34*80829ec8SRene Gollent 	uint8 yOffset = 0;
35*80829ec8SRene Gollent 
36*80829ec8SRene Gollent 	if (x < 0) {
37*80829ec8SRene Gollent 		xOffset = -x;
38*80829ec8SRene Gollent 		x = 0;
39*80829ec8SRene Gollent 	}
40*80829ec8SRene Gollent 
41*80829ec8SRene Gollent 	if (y < 0) {
42*80829ec8SRene Gollent 		yOffset = -y;
43*80829ec8SRene Gollent 		y = 0;
44*80829ec8SRene Gollent 	}
45*80829ec8SRene Gollent 
46*80829ec8SRene Gollent 	OUTREG(CUR_OFFSET, (si.cursorOffset >> 3) + (yOffset << 1));
47*80829ec8SRene Gollent 	OUTREG(CUR_HORZ_VERT_OFF, (yOffset << 16) | xOffset);
48*80829ec8SRene Gollent 	OUTREG(CUR_HORZ_VERT_POSN, (y << 16) | x);
49*80829ec8SRene Gollent }
50*80829ec8SRene Gollent 
51*80829ec8SRene Gollent 
52*80829ec8SRene Gollent bool
Mach64_LoadCursorImage(int width,int height,uint8 * andMask,uint8 * xorMask)53*80829ec8SRene Gollent Mach64_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask)
54*80829ec8SRene Gollent {
55*80829ec8SRene Gollent 	SharedInfo& si = *gInfo.sharedInfo;
56*80829ec8SRene Gollent 
57*80829ec8SRene Gollent 	if (andMask == NULL || xorMask == NULL)
58*80829ec8SRene Gollent 		return false;
59*80829ec8SRene Gollent 
60*80829ec8SRene Gollent 	uint16* fbCursor = (uint16*)((addr_t)si.videoMemAddr + si.cursorOffset);
61*80829ec8SRene Gollent 
62*80829ec8SRene Gollent 	// Initialize the hardware cursor as completely transparent.
63*80829ec8SRene Gollent 
64*80829ec8SRene Gollent 	memset(fbCursor, 0xaa, CURSOR_BYTES);
65*80829ec8SRene Gollent 
66*80829ec8SRene Gollent 	// Now load the AND & XOR masks for the cursor image into the cursor
67*80829ec8SRene Gollent 	// buffer.  Note that a particular bit in these masks will have the
68*80829ec8SRene Gollent 	// following effect upon the corresponding cursor pixel:
69*80829ec8SRene Gollent 	//	AND  XOR	Result
70*80829ec8SRene Gollent 	//	 0    0		 White pixel
71*80829ec8SRene Gollent 	//	 0    1		 Black pixel
72*80829ec8SRene Gollent 	//	 1    0		 Screen color (for transparency)
73*80829ec8SRene Gollent 	//	 1    1		 Reverse screen color to black or white
74*80829ec8SRene Gollent 
75*80829ec8SRene Gollent 	for (int row = 0; row < height; row++) {
76*80829ec8SRene Gollent 		for (int colByte = 0; colByte < width / 8; colByte++) {
77*80829ec8SRene Gollent 			// Convert the 8 bit AND and XOR masks into a 16 bit mask containing
78*80829ec8SRene Gollent 			// pairs of the bits from the AND and XOR maks.
79*80829ec8SRene Gollent 
80*80829ec8SRene Gollent 			uint8 andBits = *andMask++;
81*80829ec8SRene Gollent 			uint8 xorBits = *xorMask++;
82*80829ec8SRene Gollent 			uint16 cursorBits = 0;
83*80829ec8SRene Gollent 
84*80829ec8SRene Gollent 			for (int j = 0; j < 8; j++) {
85*80829ec8SRene Gollent 				cursorBits <<= 2;
86*80829ec8SRene Gollent 				cursorBits |= ((andBits & 0x01) << 1);
87*80829ec8SRene Gollent 				cursorBits |= (xorBits & 0x01);
88*80829ec8SRene Gollent 				andBits >>= 1;
89*80829ec8SRene Gollent 				xorBits >>= 1;
90*80829ec8SRene Gollent 			}
91*80829ec8SRene Gollent 
92*80829ec8SRene Gollent 			fbCursor[row * 8 + colByte] = cursorBits;
93*80829ec8SRene Gollent 		}
94*80829ec8SRene Gollent 	}
95*80829ec8SRene Gollent 
96*80829ec8SRene Gollent 	// Set the cursor colors which are white background and black foreground.
97*80829ec8SRene Gollent 
98*80829ec8SRene Gollent 	OUTREG(CUR_CLR0, ~0);
99*80829ec8SRene Gollent 	OUTREG(CUR_CLR1, 0);
100*80829ec8SRene Gollent 
101*80829ec8SRene Gollent 	return true;
102*80829ec8SRene Gollent }
103