]> git.vomp.tv Git - vompclient.git/blob - wwss.cc
Preparations for dynamic mode switching
[vompclient.git] / wwss.cc
1 /*
2     Copyright 2006 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19 */
20
21 #include "wwss.h"
22
23 #include "colour.h"
24 #include "video.h"
25
26 Wwss::Wwss()
27 {
28   format = Video::NTSC;
29 }
30
31 Wwss::~Wwss()
32 {
33 }
34
35 void Wwss::setFormat(UCHAR tformat)
36 {
37   format = tformat;
38 }
39
40 UINT Wwss::gcd(UINT a, UINT b)
41 {
42   UINT t;
43   while (b != 0)
44   {
45     t = b;
46     b = a % b;
47     a = t;
48   }
49   return a;
50 }
51
52 UINT Wwss::lcm(UINT a, UINT b)
53 {
54   return (a / gcd(a, b)) * b;
55 }
56
57 void Wwss::setWide(bool twide)
58 {
59   wide = twide;
60 }
61
62 void Wwss::draw()
63 {
64   if (format == Video::PAL) drawPAL();
65 //  else if (format == Video::NTSC) drawNTSC();
66 }
67
68 void Wwss::drawPAL()
69 {
70   // The aspect43 and aspect169 codes are not what they should be according to the docs, but these are what work...
71   // (1 = 111000, = 0 000111)
72   static UCHAR runIn[]     = {1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1};                       // 29 pos 0
73   static UCHAR startCode[] = {0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1};                                 // 24 pos 29
74   static UCHAR aspect43[]  = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,1,1,1,0,0,0}; // = 0001   4:3 full frame      // 24 pos 53
75   static UCHAR aspect169[] = {1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1}; // = 1110   16:9 anamorphic     // 24 pos 53
76   static UCHAR theRest[]   = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,                                  // 60 pos 77
77                               0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1,
78                               0,0,0,1,1,1,0,0,0,1,1,1};
79   /*
80   Real PAL pixel frequency: 13.5 MHz
81   WSS element frequency: 5 MHz
82   = 2.7 pal pixels per wss element
83   * 137 wss elements = 369.9 pal pixels (total code width) (round to 370..)
84
85   There is also a 11us gap at the start of the pal raster, but since I don't really have any
86   idea where our 720 pixels start in the raster I can't calculate an offset.
87
88   PAL line 23 seems to be MVP line 6.
89   */
90
91   const UINT   Ns = 137;           // Num pix src
92   const UINT   Nd = 370;           // Num pix dst         359->395 does something. not the right thing, but something.
93   UINT         Nl = lcm(Ns, Nd);   // Num pix in lcm
94   UINT         Ss = Nl / Ns;       // Source split (how many lcm px = 1 src px)
95   UINT         Sd = Nl / Nd;       // Dst split
96   UCHAR src[Ns];
97
98   memcpy(&src[0], runIn, 29);
99   memcpy(&src[29], startCode, 24);
100   if (wide) memcpy(&src[53], aspect169, 24);
101   else      memcpy(&src[53], aspect43, 24);
102   memcpy(&src[77], theRest, 60);
103
104   float dst[Nd];
105   UINT lcmpxbase = 0;
106
107   for(UINT t = 0; t < Nd; t++) // for every destination pixel
108   {
109     dst[t] = 0;
110     for(UINT lcmpx = lcmpxbase; lcmpx < (lcmpxbase + Sd); lcmpx++)
111     {
112       if (src[lcmpx / Ss]) dst[t] += (float)1/Sd;
113     }
114     lcmpxbase += Sd;
115   }
116
117   Colour c;
118   UINT value;
119
120   for(UINT q = 0; q < Nd; q++)
121   {
122     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value
123     c.set(value, value, value);
124     getSurface()->drawPixel(q, 6, c);
125   }
126 }
127
128 void Wwss::drawNTSC()
129 {
130 /*
131   static UCHAR startCode[] = {1,0,0,0,0,0,0};
132   static UCHAR aspect43[]  = {0};
133   static UCHAR aspect169[] = {1};
134   static UCHAR theRest[]   = {0,0,0,0,0,0,0,0};
135   static UCHAR crc43[]     = {0,0,0,0,0,0};
136   static UCHAR crc169[]    = {0,0,1,1,0,0};
137 */
138   /*
139   Real NTSC pixel frequency: 13.5 MHz
140   WSS bit frequency: 447.443125 kHz
141   = 30.1714 NTSC pixels per wss bit
142   * 22 wss bits = 663.7715 NTSC pixels (total code width) (round to 664..)
143
144   There is also a 11.2us gap at the start of the pal raster, but since I don't really have any
145   idea where our 720 pixels start in the raster I can't calculate an offset.
146
147   PAL line 23 seems to be MVP line 6.
148   */
149
150   const UINT   Ns = 22;            // Num pix src
151   const UINT   Nd = 664;           // Num pix dst
152 //  const UINT   Nd = 518;           // Num pix dst
153   UINT         Nl = lcm(Ns, Nd);   // Num pix in lcm
154   UINT         Ss = Nl / Ns;       // Source split (how many lcm px = 1 src px)
155   UINT         Sd = Nl / Nd;       // Dst split
156 //  UCHAR src[Ns];
157
158 /*
159   memcpy(&src[0], startCode, 7);
160   if (wide) memcpy(&src[7], aspect169, 1);
161   else      memcpy(&src[7], aspect43, 1);
162   memcpy(&src[8], theRest, 8);
163   if (wide) memcpy(&src[16], crc169, 6);
164   else      memcpy(&src[16], crc43, 6);
165 */
166
167 static UCHAR src[22] = {1,0, 0,0,0,0,1,1, 0,0,0,0, 0,0,0,0, 0,0,1,0,0,1 };
168
169
170   float dst[Nd];
171   UINT lcmpxbase = 0;
172
173   for(UINT t = 0; t < Nd; t++) // for every destination pixel
174   {
175     dst[t] = 0;
176     for(UINT lcmpx = lcmpxbase; lcmpx < (lcmpxbase + Sd); lcmpx++)
177     {
178       if (src[lcmpx / Ss]) dst[t] += (float)1/Sd;
179     }
180     lcmpxbase += Sd;
181   }
182
183   Colour c;
184   UINT value;
185
186 // This one is the real one
187 /*
188   for(UINT q = 0; q < Nd; q++)
189   {
190     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value
191     c.set(value, value, value);
192     getSurface()->drawPixel(q, 6, c);
193   }
194 */
195
196 // This one is testing active
197 for(int yy = 0; yy < 100; yy++)
198 {
199   for(UINT q = 0; q < Nd; q++)
200   {
201     value = (UINT)(dst[q] * 182); // Apparently this is a better number than 255 for the colour value
202     c.set(value, value, value);
203     getSurface()->drawPixel(q+0, yy, c);
204   }
205 }
206
207
208
209 }
210
211 /*
212 x6 + x + 1
213
214 1x6 + 0x5 + 0x4 + 0x3 + 0x2 + 1x1 + 1x0
215 =
216 1      0     0     0     0     1     1
217 =
218 1000011
219 key width = 6
220
221 static UCHAR startCode[] = {1,0};
222 static UCHAR aspect43[]  = {0,0};
223 static UCHAR aspect169[] = {1,0};
224 static UCHAR theRest[]   = {0,0,0,0,0,0,0,0,0,0,0,0};
225 static UCHAR crc43[]     = {0,0,0,0,0,0};
226 static UCHAR crc169[]    = {0,0,1,0,0,1};
227
228 Message 4:3
229
230 1000000000000000
231
232 Message 4:3 augmented
233
234 1000000000000000000000
235
236 Key
237
238 1000011
239
240
241 Ho ho, polynomial long division. Yeeeeaaahhh I remember
242 doing *that*. Of course I do. If you know of a faster,
243 easier, more reliable way of doing this, please let me know.
244
245
246                  100
247          ________________________
248 1000011  ) 1000000000000000000000
249            1000011
250            -------
251             0000110
252             0000000
253             -------
254              0001100
255
256
257
258
259
260
261 Message 16:9
262
263 1010000000000000
264
265 Message 4:3 augmented
266
267 1010000000000000000000
268
269 Key
270
271 1000011
272
273                  1010011110100011
274          ________________________
275 1000011  ) 1010000000000000000000
276            1000011
277             -------
278             0100110
279             0000000
280              -------
281              1001100
282              1000011
283               -------
284               0011110
285               0000000
286                -------
287                0111100
288                0000000
289                 -------
290                 1111000
291                 1000011
292                  -------
293                  1110110
294                  1000011
295                   -------
296                   1101010
297                   1000011
298                    -------
299                    1010010
300                    1000011
301                     -------
302                     0100010
303                     0000000
304                      -------
305                      1000100
306                      1000011
307                       -------
308                       0001110
309                       0000000
310                        -------
311                        0011100
312                        0000000
313                         -------
314                         0111000
315                         0000000
316                          -------
317                          1110000
318                          1000011
319                           -------
320                           1100110
321                           1000011
322                           -------
323                            100101
324 */