]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/2600/tia.c
demote libemu to common code
[plan9front.git] / sys / src / games / 2600 / tia.c
1 #include <u.h>
2 #include <libc.h>
3 #include "../eui.h"
4 #include "dat.h"
5 #include "fns.h"
6
7 int ppux=1, ppuy;
8 int col, pri;
9 u8int p0x, p1x, m0x, m1x, blx;
10 u16int coll;
11 u8int disp;
12 int p0difc;
13 int bwmod = 1<<3;
14
15 enum {
16         SRCPF,
17         SRCP0,
18         SRCP1,
19         SRCM0,
20         SRCM1,
21         SRCBL,
22 };
23
24 static void
25 pixeldraw(u8int v)
26 {
27         u32int c;
28         union { u32int l; u8int c[4]; } u;
29         u32int *p;
30         static u32int col[] = {
31                 0x000000, 0x404040, 0x6C6C6C, 0x909090, 0xB0B0B0, 0xC8C8C8, 0xDCDCDC, 0xECECEC, 
32                 0x444400, 0x646410, 0x848424, 0xA0A034, 0xB8B840, 0xD0D050, 0xE8E85C, 0xFCFC68, 
33                 0x702800, 0x844414, 0x985C28, 0xAC783C, 0xBC8C4C, 0xCCA05C, 0xDCB468, 0xECC878, 
34                 0x841800, 0x983418, 0xAC5030, 0xC06848, 0xD0805C, 0xE09470, 0xECA880, 0xFCBC94, 
35                 0x880000, 0x9C2020, 0xB03C3C, 0xC05858, 0xD07070, 0xE08888, 0xECA0A0, 0xFCB4B4, 
36                 0x78005C, 0x8C2074, 0xA03C88, 0xB0589C, 0xC070B0, 0xD084C0, 0xDC9CD0, 0xECB0E0, 
37                 0x480078, 0x602090, 0x783CA4, 0x8C58B8, 0xA070CC, 0xB484DC, 0xC49CEC, 0xD4B0FC, 
38                 0x140084, 0x302098, 0x4C3CAC, 0x6858C0, 0x7C70D0, 0x9488E0, 0xA8A0EC, 0xBCB4FC, 
39                 0x000088, 0x1C209C, 0x3840B0, 0x505CC0, 0x6874D0, 0x7C8CE0, 0x90A4EC, 0xA4B8FC, 
40                 0x00187C, 0x1C3890, 0x3854A8, 0x5070BC, 0x6888CC, 0x7C9CDC, 0x90B4EC, 0xA4C8FC, 
41                 0x002C5C, 0x1C4C78, 0x386890, 0x5084AC, 0x689CC0, 0x7CB4D4, 0x90CCE8, 0xA4E0FC, 
42                 0x003C2C, 0x1C5C48, 0x387C64, 0x509C80, 0x68B494, 0x7CD0AC, 0x90E4C0, 0xA4FCD4, 
43                 0x003C00, 0x205C20, 0x407C40, 0x5C9C5C, 0x74B474, 0x8CD08C, 0xA4E4A4, 0xB8FCB8, 
44                 0x143800, 0x345C1C, 0x507C38, 0x6C9850, 0x84B468, 0x9CCC7C, 0xB4E490, 0xC8FCA4, 
45                 0x2C3000, 0x4C501C, 0x687034, 0x848C4C, 0x9CA864, 0xB4C078, 0xCCD488, 0xE0EC9C, 
46                 0x442800, 0x644818, 0x846830, 0xA08444, 0xB89C58, 0xD0B46C, 0xE8CC7C, 0xFCE08C, 
47         };
48         
49         c = col[v >> 1];
50         u.c[0] = c;
51         u.c[1] = c >> 8;
52         u.c[2] = c >> 16;
53         u.c[3] = 0xff;
54         p = (u32int *)pic + ppuy * PICW * scale + ppux * 2 * scale;
55         switch(scale){
56         case 16: *p++ = u.l; *p++ = u.l;
57         case 15: *p++ = u.l; *p++ = u.l;
58         case 14: *p++ = u.l; *p++ = u.l;
59         case 13: *p++ = u.l; *p++ = u.l;
60         case 12: *p++ = u.l; *p++ = u.l;
61         case 11: *p++ = u.l; *p++ = u.l;
62         case 10: *p++ = u.l; *p++ = u.l;
63         case 9: *p++ = u.l; *p++ = u.l;
64         case 8: *p++ = u.l; *p++ = u.l;
65         case 7: *p++ = u.l; *p++ = u.l;
66         case 6: *p++ = u.l; *p++ = u.l;
67         case 5: *p++ = u.l; *p++ = u.l;
68         case 4: *p++ = u.l; *p++ = u.l;
69         case 3: *p++ = u.l; *p++ = u.l;
70         case 2: *p++ = u.l; *p++ = u.l;
71         default: *p++ = u.l; *p = u.l;
72         }
73 }
74
75 static void
76 pixel(u8int v, int p, int s)
77 {
78         if(p > pri){
79                 col = v;
80                 pri = p;
81         }
82         disp |= 1<<s;
83 }
84
85 static void
86 playfield(void)
87 {
88         int x, p;
89         u8int c;
90         
91         x = ppux / 4;
92         if(x >= 20)
93                 if((reg[CTRLPF] & 1) != 0)
94                         x = 39 - x;
95                 else
96                         x = x - 20;
97         if(x < 4){
98                 if((reg[PF0] & 0x10<<x) == 0)
99                         return;
100         }else if(x < 12){
101                 if((reg[PF1] & 0x800>>x) == 0)
102                         return;
103         }else
104                 if((reg[PF2] & 1<<x-12) == 0)
105                         return;
106         if((reg[CTRLPF] & 6) == 2)
107                 if(ppux < 80){
108                         c = reg[COLUP0];
109                         p = 3;
110                 }else{
111                         c = reg[COLUP1];
112                         p = 2;
113                 }
114         else{
115                 c = reg[COLUPF];
116                 p = (reg[CTRLPF] & 4) + 1;
117         }
118         pixel(c, p, SRCPF);
119 }
120
121 static void
122 player(int n)
123 {
124         u8int c;
125         int x;
126
127         c = reg[GRP0 + n];
128         x = ppux - (n ? p1x : p0x);
129         if(x < 0)
130                 return;
131         switch(reg[NUSIZ0 + n] & 7){
132         default: if(x >= 8) return; break;
133         case 1: if(x >= 8 && (x < 16 || x >= 24)) return; break;
134         case 2: if(x >= 8 && (x < 32 || x >= 40)) return; break;
135         case 3: if(x >= 40 || ((x & 15) >= 8)) return; break;
136         case 4: if(x >= 8 && (x < 64 || x >= 72)) return; break;
137         case 5: if(x >= 16) return; x >>= 1; break;
138         case 6: if(x >= 72 || ((x & 31) >= 8)) return; break;
139         case 7: if(x >= 32) return; x >>= 2; break;
140         }
141         x &= 7;
142         if((reg[REFP0 + n] & 8) == 0)
143                 x ^= 7;
144         if((c & 1<<x) == 0)
145                 return;
146         c = reg[COLUP0 + n];
147         pixel(c, 3 - n, SRCP0 + n);
148 }
149
150 static void
151 missile(int n)
152 {
153         int x;
154
155         x = ppux - (n ? m1x : m0x);
156         if((reg[RESMP0 + n] & 2) != 0){
157                 if(n)
158                         m1x = p1x;
159                 else
160                         m0x = p0x;
161                 return;
162         }
163         if(x < 0 || x >= 1<<(reg[NUSIZ0] >> 4 & 3) || (reg[ENAM0 + n] & 2) == 0)
164                 return;
165         pixel(reg[COLUP0 + n], 3 - n, SRCM0 + n);
166 }
167
168 static void
169 ball(void)
170 {
171         int x;
172
173         x = ppux - blx;
174         if(x < 0 || x >= 1<<(reg[CTRLPF] >> 4 & 3) || (reg[ENABL] & 2) == 0)
175                 return;
176         pixel(reg[COLUPF], (reg[CTRLPF] & 4) + 1, SRCBL);
177 }
178
179 void
180 tiastep(void)
181 {
182         static u16int colltab[64] = {
183                 0x0000, 0x0000, 0x0000, 0x0020, 0x0000, 0x0080, 0x8000, 0x80a0,
184                 0x0000, 0x0200, 0x0001, 0x0221, 0x0002, 0x0282, 0x8003, 0x82a3,
185                 0x0000, 0x0800, 0x0008, 0x0828, 0x0004, 0x0884, 0x800c, 0x88ac,
186                 0x4000, 0x4a00, 0x4009, 0x4a29, 0x4006, 0x4a86, 0xc00f, 0xcaaf,
187                 0x0000, 0x2000, 0x0010, 0x2030, 0x0040, 0x20c0, 0x8050, 0xa0f0,
188                 0x0100, 0x2300, 0x0111, 0x2331, 0x0142, 0x23c2, 0x8153, 0xa3f3,
189                 0x0400, 0x2c00, 0x0418, 0x2c38, 0x0444, 0x2cc4, 0x845c, 0xacfc,
190                 0x4500, 0x6f00, 0x4519, 0x6f39, 0x4546, 0x6fc6, 0xc55f, 0xefff,
191         };
192
193         if(ppuy < PICH && ppux < 160){
194                 col = reg[COLUBK];
195                 pri = 0;
196                 disp = 0;
197                 playfield();
198                 player(0);
199                 player(1);
200                 missile(0);
201                 missile(1);
202                 ball();
203                 coll |= colltab[disp];
204                 pixeldraw(col);
205         }
206         if(ppux == 160)
207                 nrdy = 0;
208         if(++ppux == 228){
209                 ppuy++;
210                 ppux = 0;
211         }
212 }