|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * OS specific functions
5: *
6: * (c) 1995 Bernd Schmidt
7: */
8:
9: #include <stdio.h>
10:
11: #ifdef __unix
12: #include <values.h>
13: #include <fcntl.h>
14: #include <unistd.h>
15: #endif
16:
17: #include "config.h"
18: #include "amiga.h"
19: #include "options.h"
20: #include "memory.h"
21: #include "custom.h"
22: #include "os.h"
23:
24: #ifdef LINUX_JOYSTICK
25:
26: #include <linux/joystick.h>
27:
28: static int js0;
29: static bool joystickpresent = false;
30:
31: struct JS_DATA_TYPE jscal;
32:
33: void read_joystick(UWORD *dir, bool *button)
34: {
35: static int minx = MAXINT, maxx = MININT,
36: miny = MAXINT, maxy = MININT;
37: bool left = false, right = false, top = false, bot = false;
38: struct JS_DATA_TYPE buffer;
39: int len;
40:
41: *dir = 0;
42: *button = false;
43: if (!joystickpresent)
44: return;
45:
46: len = read(js0, &buffer, sizeof(buffer));
47: if (len != sizeof(buffer))
48: return;
49:
50: if (buffer.x < minx) minx = buffer.x;
51: if (buffer.y < miny) miny = buffer.y;
52: if (buffer.x > maxx) maxx = buffer.x;
53: if (buffer.y > maxy) maxy = buffer.y;
54:
55: if (buffer.x < (minx + (maxx-minx)/3))
56: left = true;
57: else if (buffer.x > (minx + 2*(maxx-minx)/3))
58: right = true;
59:
60: if (buffer.y < (miny + (maxy-miny)/3))
61: top = true;
62: else if (buffer.y > (miny + 2*(maxy-miny)/3))
63: bot = true;
64:
65: if (left) top = !top;
66: if (right) bot = !bot;
67: *dir = bot | (right << 1) | (top << 8) | (left << 9);
68: *button = (buffer.buttons & 3) != 0;
69: }
70:
71: void init_joystick(void)
72: {
73: js0 = open("/dev/js0", O_RDONLY);
74: if (js0 < 0)
75: return;
76: joystickpresent = true;
77: }
78:
79: void close_joystick(void)
80: {
81: if (joystickpresent)
82: close(js0);
83: }
84: #else
85:
86: void read_joystick(UWORD *dir, bool *button)
87: {
88: *dir = 0;
89: *button = false;
90: }
91:
92: void init_joystick(void)
93: {
94: }
95:
96: void close_joystick(void)
97: {
98: }
99: #endif
100:
101: CPTR audlc[4], audpt[4];
102: UWORD audvol[4], audper[4], audlen[4], audwlen[4];
103: int audwper[4];
104: UWORD auddat[4];
105: int audsnum[4];
106:
107: /* Audio states. This is not an exact representation of the Audio State Machine
108: * (HRM p. 166), but a simplification. To be honest, I don't completely
109: * understand that picture yet.
110: */
111: int audst[4];
112:
113: #ifdef LINUX_SOUND
114:
115: #include <sys/soundcard.h>
116:
117: static const int n_frames = 10;
118:
119: /* The buffer is too large... */
120: static UWORD buffer[44100], *bufpt;
121: static BYTE snddata[4];
122:
123: static int frames = 0;
124: static int smplcnt = 0;
125:
126: static int sfd;
127: static bool have_sound;
128:
129: bool init_sound (void)
130: {
131: int tmp;
132: sfd = open ("/dev/dsp", O_WRONLY);
133: have_sound = !(sfd < 0);
134: if (!have_sound) {
135: return false;
136: }
137:
138: tmp = 16;
139: ioctl(sfd, SNDCTL_DSP_SAMPLESIZE, &tmp);
140:
141: tmp = 0;
142: ioctl(sfd, SNDCTL_DSP_STEREO, &tmp);
143:
144: tmp = 44100;
145: ioctl(sfd, SNDCTL_DSP_SPEED, &tmp);
146:
147: audst[0] = audst[1] = audst[2] = audst[3] = 0;
148: bufpt = buffer;
149: frames = n_frames;
150: smplcnt = 0;
151: return true;
152: }
153:
154: static void channel_reload (int c)
155: {
156: audst[c] = 1;
157: audpt[c] = audlc[c];
158: audwper[c] = 0;
159: audwlen[c] = audlen[c];
160: audsnum[c] = 1;
161: }
162:
163: void do_sound (void)
164: {
165: smplcnt -= 227;
166: while (smplcnt < 0) {
167: int i;
168: smplcnt += 80;
169: for(i = 0; i < 4; i++) {
170: if (dmaen (1<<i)) {
171: if (audst[i] == 0) {
172: /* DMA was turned on for this channel */
173: channel_reload (i);
174: continue;
175: }
176:
177: if (audwper[i] <= 0) {
178: audwper[i] += audper[i];
179: if (audst[i] == 1) {
180: /* Starting a sample, cause interrupt */
181: put_word (0xDFF09C, 0x8000 | (0x80 << i));
182: audst[i] = 2;
183: }
184: audsnum[i] ^= 1;
185: if (audsnum[i] == 0) {
186: auddat[i] = get_word (audpt[i]);
187: audpt[i] += 2;
188: audwlen[i]--;
189: if (audwlen[i] == 0) {
190: channel_reload (i);
191: }
192: }
193: }
194: snddata[i] = audsnum[i] ? auddat[i] : auddat[i] >> 8;
195: audwper[i] -= 80;
196: } else
197: audst[i] = snddata[i] = 0;
198: }
199: *bufpt++ = (snddata[0] * audvol[0] / 2 + snddata[1] * audvol[1] / 2
200: + snddata[2] * audvol[2] / 2 + snddata[3] * audvol[3] / 2);
201: }
202: }
203:
204: void flush_sound (void)
205: {
206: if (--frames == 0) {
207: write (sfd, buffer, 2*(bufpt - buffer));
208: bufpt = buffer;
209: frames = n_frames;
210: }
211: }
212:
213: #else
214: bool init_sound (void)
215: {
216: return true;
217: }
218:
219: void do_sound (void)
220: {
221: }
222:
223: void flush_sound (void)
224: {
225: }
226: #endif
227:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.