Added 'wine' prefix to libwine_unicode exports.
[wine] / dlls / d3d8 / vshaderdeclaration.c
1 /*
2  * vertex shaders declaration implementation
3  *
4  * Copyright 2002 Raphael Junqueira
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "windef.h"
22 #include "winbase.h"
23 #include "winuser.h"
24 #include "wingdi.h"
25 #include "wine/debug.h"
26
27 #include <math.h>
28
29 #include "d3d8_private.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32
33 /**
34  * DirectX9 SDK download
35  *  http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp
36  *
37  * Exploring D3DX
38  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx07162002.asp
39  *
40  * Using Vertex Shaders
41  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx02192001.asp
42  *
43  * Dx9 New
44  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/whatsnew.asp
45  *
46  * Dx9 Shaders
47  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/VertexShader2_0.asp
48  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader2_0/Instructions/Instructions.asp
49  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexDeclaration/VertexDeclaration.asp
50  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/reference/Shaders/VertexShader3_0/VertexShader3_0.asp
51  *
52  * Dx9 D3DX
53  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/programmingguide/advancedtopics/VertexPipe/matrixstack/matrixstack.asp
54  *
55  * FVF
56  *  http://msdn.microsoft.com/library/en-us/directx9_c/directx/graphics/programmingguide/GettingStarted/VertexFormats/vformats.asp
57  *
58  * NVIDIA: DX8 Vertex Shader to NV Vertex Program
59  *  http://developer.nvidia.com/view.asp?IO=vstovp
60  *
61  * NVIDIA: Memory Management with VAR
62  *  http://developer.nvidia.com/view.asp?IO=var_memory_management 
63  */
64
65 /** Vertex Shader Declaration data types tokens */
66 static CONST char* VertexShaderDeclDataTypes [] = {
67   "D3DVSDT_FLOAT1",
68   "D3DVSDT_FLOAT2",
69   "D3DVSDT_FLOAT3",
70   "D3DVSDT_FLOAT4",
71   "D3DVSDT_D3DCOLOR",
72   "D3DVSDT_UBYTE4",
73   "D3DVSDT_SHORT2",
74   "D3DVSDT_SHORT4",
75   NULL
76 };
77
78 static CONST char* VertexShaderDeclRegister [] = {
79   "D3DVSDE_POSITION",
80   "D3DVSDE_BLENDWEIGHT",
81   "D3DVSDE_BLENDINDICES",
82   "D3DVSDE_NORMAL",
83   "D3DVSDE_PSIZE",
84   "D3DVSDE_DIFFUSE",
85   "D3DVSDE_SPECULAR",
86   "D3DVSDE_TEXCOORD0",
87   "D3DVSDE_TEXCOORD1",
88   "D3DVSDE_TEXCOORD2",
89   "D3DVSDE_TEXCOORD3",
90   "D3DVSDE_TEXCOORD4",
91   "D3DVSDE_TEXCOORD5",
92   "D3DVSDE_TEXCOORD6",
93   "D3DVSDE_TEXCOORD7",
94   "D3DVSDE_POSITION2",
95   "D3DVSDE_NORMAL2",
96   NULL
97 };
98
99 /** todo check decl validity */
100 inline static DWORD Direct3DVextexShaderDeclarationImpl_ParseToken(const DWORD* pToken) {
101   const DWORD token = *pToken;
102   DWORD tokenlen = 1;
103
104   switch ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT) { /* maybe a macro to inverse ... */
105   case D3DVSD_TOKEN_NOP:
106     TRACE(" 0x%08lx NOP()\n", token);
107     break;
108   case D3DVSD_TOKEN_STREAM:
109     if (token & D3DVSD_STREAMTESSMASK) {
110       TRACE(" 0x%08lx STREAM_TESS()\n", token);
111     } else {
112       TRACE(" 0x%08lx STREAM(%lu)\n", token, ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT));
113     }
114     break;
115   case D3DVSD_TOKEN_STREAMDATA:
116     if (token & 0x10000000) {
117       TRACE(" 0x%08lx SKIP(%lu)\n", token, ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT));
118     } else {
119       DWORD type = ((token & D3DVSD_DATATYPEMASK)  >> D3DVSD_DATATYPESHIFT);
120       DWORD reg  = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
121       TRACE(" 0x%08lx REG(%s, %s)\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]);
122     }
123     break;
124   case D3DVSD_TOKEN_TESSELLATOR:
125     if (token & 0x10000000) {
126       DWORD type = ((token & D3DVSD_DATATYPEMASK)  >> D3DVSD_DATATYPESHIFT);
127       DWORD reg  = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
128       TRACE(" 0x%08lx TESSUV(%s) as %s\n", token, VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]);
129     } else {
130       DWORD type   = ((token & D3DVSD_DATATYPEMASK)    >> D3DVSD_DATATYPESHIFT);
131       DWORD regout = ((token & D3DVSD_VERTEXREGMASK)   >> D3DVSD_VERTEXREGSHIFT);
132       DWORD regin  = ((token & D3DVSD_VERTEXREGINMASK) >> D3DVSD_VERTEXREGINSHIFT);
133       TRACE(" 0x%08lx TESSNORMAL(%s, %s) as %s\n", token, VertexShaderDeclRegister[regin], VertexShaderDeclRegister[regout], VertexShaderDeclDataTypes[type]);
134     }
135     break;
136   case D3DVSD_TOKEN_CONSTMEM:
137     {
138       DWORD i;
139       DWORD count        = ((token & D3DVSD_CONSTCOUNTMASK)   >> D3DVSD_CONSTCOUNTSHIFT);
140       DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
141       TRACE(" 0x%08lx CONST(%lu, %lu)\n", token, constaddress, count);
142       ++pToken;
143       for (i = 0; i < count; ++i) {
144         TRACE("        c[%lu] = (0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx)\n", 
145                 constaddress, 
146                 *pToken, 
147                 *(pToken + 1), 
148                 *(pToken + 2), 
149                 *(pToken + 3));
150         pToken += 4; 
151         ++constaddress;
152       }
153       tokenlen = count + 1;
154     }
155     break;
156   case D3DVSD_TOKEN_EXT:
157     {
158       DWORD count   = ((token & D3DVSD_CONSTCOUNTMASK) >> D3DVSD_CONSTCOUNTSHIFT);
159       DWORD extinfo = ((token & D3DVSD_EXTINFOMASK)    >> D3DVSD_EXTINFOSHIFT);
160       TRACE(" 0x%08lx EXT(%lu, %lu)\n", token, count, extinfo);
161       /* todo ... print extension */
162       tokenlen = count + 1;
163     }
164     break;
165   case D3DVSD_TOKEN_END:
166     TRACE(" 0x%08lx END()\n", token);
167     break;
168   default:
169     TRACE(" 0x%08lx UNKNOWN\n", token);
170     /* argg error */
171   }
172   return tokenlen;
173 }
174
175 HRESULT WINAPI IDirect3DDeviceImpl_CreateVertexShaderDeclaration8(IDirect3DDevice8Impl* This, CONST DWORD* pDeclaration8, IDirect3DVertexShaderDeclarationImpl** ppVertexShaderDecl) {
176   /** parser data */
177   const DWORD* pToken = pDeclaration8;
178   DWORD fvf = 0;
179   DWORD len = 0;  
180   DWORD stream = 0;
181   DWORD token;
182   DWORD tokenlen;
183   DWORD tokentype;
184   DWORD tex = D3DFVF_TEX0;
185   /** TRUE if declaration can be matched by a fvf */
186   IDirect3DVertexShaderDeclarationImpl* object;
187   BOOL  invalid_fvf = FALSE;
188
189   TRACE("(%p) :  pDeclaration8(%p)\n", This, pDeclaration8);
190
191   object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexShaderDeclarationImpl));
192   /*object->lpVtbl = &Direct3DVextexShaderDeclaration8_Vtbl;*/
193   object->device = This; /* FIXME: AddRef(This) */
194   object->ref = 1;
195
196   while (D3DVSD_END() != *pToken) {
197     token = *pToken;
198     tokenlen = Direct3DVextexShaderDeclarationImpl_ParseToken(pToken); 
199     tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
200     
201     /** FVF generation block */
202     if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
203       /** 
204        * how really works streams, 
205        *  in DolphinVS dx8 dsk sample they seems to decal reg numbers !!!
206        */
207       stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
208
209       if (stream > 0) {
210         /** fvf cannot map mutliple streams, so invalid fvf computing */
211         invalid_fvf = TRUE;
212       }
213
214     } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
215       DWORD type = ((token & D3DVSD_DATATYPEMASK)  >> D3DVSD_DATATYPESHIFT);
216       DWORD reg  = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT) - stream;
217
218       switch (reg) {
219       case D3DVSDE_POSITION:     
220         switch (type) {
221         case D3DVSDT_FLOAT3:     fvf |= D3DFVF_XYZ;             break;
222         case D3DVSDT_FLOAT4:     fvf |= D3DFVF_XYZRHW;          break;
223         default: 
224           /** errooooorr mismatched use of a register, invalid fvf computing */
225           invalid_fvf = TRUE;
226           TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
227         }
228         break;
229
230       case D3DVSDE_BLENDWEIGHT:
231         switch (type) {
232         case D3DVSDT_FLOAT1:     fvf |= D3DFVF_XYZB1;           break;
233         case D3DVSDT_FLOAT2:     fvf |= D3DFVF_XYZB2;           break;
234         case D3DVSDT_FLOAT3:     fvf |= D3DFVF_XYZB3;           break;
235         case D3DVSDT_FLOAT4:     fvf |= D3DFVF_XYZB4;           break;
236         default: 
237           /** errooooorr mismatched use of a register, invalid fvf computing */
238           invalid_fvf = TRUE;
239           TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
240         }
241         break;
242
243       case D3DVSDE_BLENDINDICES: /* seem to be B5 as said in MSDN Dx9SDK ??  */
244         switch (type) {
245         case D3DVSDT_UBYTE4:     fvf |= D3DFVF_LASTBETA_UBYTE4;           break;
246         default: 
247           /** errooooorr mismatched use of a register, invalid fvf computing */
248           invalid_fvf = TRUE;
249           TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
250         }
251         break; 
252
253       case D3DVSDE_NORMAL: /* TODO: only FLOAT3 supported ... another choice possible ? */
254         switch (type) {
255         case D3DVSDT_FLOAT3:     fvf |= D3DFVF_NORMAL;          break;
256         default: 
257           /** errooooorr mismatched use of a register, invalid fvf computing */
258           invalid_fvf = TRUE;
259           TRACE("Mismatched use in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
260         }
261         break; 
262
263       case D3DVSDE_PSIZE:  /* TODO: only FLOAT1 supported ... another choice possible ? */
264         switch (type) {
265         case D3DVSDT_FLOAT1:     fvf |= D3DFVF_PSIZE;           break;
266         default: 
267           /** errooooorr mismatched use of a register, invalid fvf computing */
268           invalid_fvf = TRUE;
269           TRACE("Mismatched use in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
270         }
271         break;
272
273       case D3DVSDE_DIFFUSE:  /* TODO: only D3DCOLOR supported */
274         switch (type) {
275         case D3DVSDT_D3DCOLOR:   fvf |= D3DFVF_DIFFUSE;         break;
276         default: 
277           /** errooooorr mismatched use of a register, invalid fvf computing */
278           invalid_fvf = TRUE;
279           TRACE("Mismatched use in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
280         }
281         break;
282
283       case D3DVSDE_SPECULAR:  /* TODO: only D3DCOLOR supported */
284         switch (type) {
285         case D3DVSDT_D3DCOLOR:   fvf |= D3DFVF_SPECULAR;        break;
286         default: 
287           /** errooooorr mismatched use of a register, invalid fvf computing */
288           invalid_fvf = TRUE;
289           TRACE("Mismatched use in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %s\n", VertexShaderDeclDataTypes[type]);
290         }
291         break;
292
293         /**
294          * TODO: for TEX* only FLOAT2 supported
295          *  by default using texture type info
296          */
297       case D3DVSDE_TEXCOORD0:    tex = max(tex, D3DFVF_TEX1);   break; 
298       case D3DVSDE_TEXCOORD1:    tex = max(tex, D3DFVF_TEX2);   break;
299       case D3DVSDE_TEXCOORD2:    tex = max(tex, D3DFVF_TEX3);   break;
300       case D3DVSDE_TEXCOORD3:    tex = max(tex, D3DFVF_TEX4);   break;
301       case D3DVSDE_TEXCOORD4:    tex = max(tex, D3DFVF_TEX5);   break;
302       case D3DVSDE_TEXCOORD5:    tex = max(tex, D3DFVF_TEX6);   break;
303       case D3DVSDE_TEXCOORD6:    tex = max(tex, D3DFVF_TEX7);   break;
304       case D3DVSDE_TEXCOORD7:    tex = max(tex, D3DFVF_TEX8);   break;
305
306       case D3DVSDE_POSITION2:   /* maybe D3DFVF_XYZRHW instead D3DFVF_XYZ (of D3DVDE_POSITION) ... to see */
307       case D3DVSDE_NORMAL2:     /* FIXME i don't know what to do here ;( */
308         FIXME("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token);
309         break;
310       }
311       /*TRACE("VertexShader declaration define %x as current FVF\n", fvf);*/
312     }
313     len += tokenlen;
314     pToken += tokenlen;
315   }
316   if (tex > 0) {
317     /*TRACE("VertexShader declaration define %x as texture level\n", tex);*/
318     fvf |= tex;
319   }   
320   /* here D3DVSD_END() */
321   len +=  Direct3DVextexShaderDeclarationImpl_ParseToken(pToken);
322   /* copy fvf if valid */
323   if (FALSE == invalid_fvf)
324     object->fvf = fvf;
325   else
326     object->fvf = 0;
327   /* compute size */
328   object->declaration8Length = len * sizeof(DWORD);
329   /* copy the declaration */
330   object->pDeclaration8 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declaration8Length);
331   memcpy(object->pDeclaration8, pDeclaration8, object->declaration8Length);
332   /* returns */
333   *ppVertexShaderDecl = object;
334   return D3D_OK;
335 }
336
337
338 HRESULT WINAPI IDirect3DDeviceImpl_FillVertexShaderInput(IDirect3DDevice8Impl* This,
339                                                          IDirect3DVertexShaderImpl* vshader,     
340                                                          const void* vertexFirstStream,
341                                                          DWORD StartVertexIndex, 
342                                                          DWORD idxDecal) {
343   /** parser data */
344   const DWORD* pToken = This->UpdateStateBlock->vertexShaderDecl->pDeclaration8;
345   DWORD stream = 0;
346   DWORD token;
347   /*DWORD tokenlen;*/
348   DWORD tokentype;
349   /** for input readers */
350   const char* curPos = NULL;
351   FLOAT x, y, z, w;
352   SHORT u, v, r, t;
353   DWORD dw;
354
355   /*TRACE("(%p) - This:%p - stream:%p, startIdx=%lu, idxDecal=%lu\n", vshader, This, vertexFirstStream, StartVertexIndex, idxDecal);*/
356   while (D3DVSD_END() != *pToken) {
357     token = *pToken;
358     tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
359     
360     /** FVF generation block */
361     if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
362       IDirect3DVertexBuffer8* pVB;
363       const char* startVtx = NULL;
364       int skip = 0;
365
366       ++pToken;
367       /** 
368        * how really works streams, 
369        *  in DolphinVS dx8 dsk sample use it !!!
370        */
371       stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
372
373       if (0 == stream) {
374         skip = This->StateBlock->stream_stride[0];
375         startVtx = (const char*) vertexFirstStream + (StartVertexIndex * skip);
376         curPos = startVtx + idxDecal;
377         /*TRACE(" using stream[%lu] with %lu decal => curPos %p\n", stream, idxDecal, curPos);*/
378       } else {
379         skip = This->StateBlock->stream_stride[stream];
380         pVB  = This->StateBlock->stream_source[stream];
381
382         if (NULL == pVB) {
383           ERR("using unitialised stream[%lu]\n", stream);
384           return D3DERR_INVALIDCALL;
385         } else {
386           startVtx = ((IDirect3DVertexBuffer8Impl*) pVB)->allocatedMemory + (StartVertexIndex * skip);
387           /** do we need to decal if we use idxBuffer */
388           curPos = startVtx + idxDecal;
389           /*TRACE(" using stream[%lu] with %lu decal\n", stream, idxDecal);*/
390         }
391       }
392     } else if (D3DVSD_TOKEN_CONSTMEM == tokentype) {
393       /** Const decl */
394       DWORD i;
395       DWORD count        = ((token & D3DVSD_CONSTCOUNTMASK)   >> D3DVSD_CONSTCOUNTSHIFT);
396       DWORD constaddress = ((token & D3DVSD_CONSTADDRESSMASK) >> D3DVSD_CONSTADDRESSSHIFT);
397       ++pToken;
398       for (i = 0; i < count; ++i) {
399         vshader->data->C[constaddress + i].x = *(float*)pToken;
400         vshader->data->C[constaddress + i].y = *(float*)(pToken + 1);
401         vshader->data->C[constaddress + i].z = *(float*)(pToken + 2);
402         vshader->data->C[constaddress + i].w = *(float*)(pToken + 3);
403         pToken += 4;
404       }
405
406     } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 != (0x10000000 & tokentype)) {
407       /** skip datas */
408       DWORD skipCount = ((token & D3DVSD_SKIPCOUNTMASK) >> D3DVSD_SKIPCOUNTSHIFT);
409       curPos = curPos + skipCount * sizeof(DWORD);
410       ++pToken;
411
412     } else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
413       DWORD type = ((token & D3DVSD_DATATYPEMASK)  >> D3DVSD_DATATYPESHIFT);
414       DWORD reg  = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
415       ++pToken;
416
417       switch (type) {
418       case D3DVSDT_FLOAT1:
419         x = *(float*) curPos;
420         curPos = curPos + sizeof(float);
421         /**/
422         vshader->input.V[reg].x = x;
423         vshader->input.V[reg].y = 0.0f;
424         vshader->input.V[reg].z = 0.0f;
425         vshader->input.V[reg].w = 1.0f;
426         break;
427
428       case D3DVSDT_FLOAT2:
429         x = *(float*) curPos;
430         curPos = curPos + sizeof(float);
431         y = *(float*) curPos;
432         curPos = curPos + sizeof(float);
433         /**/
434         vshader->input.V[reg].x = x;
435         vshader->input.V[reg].y = y;
436         vshader->input.V[reg].z = 0.0f;
437         vshader->input.V[reg].w = 1.0f;
438         break;
439
440       case D3DVSDT_FLOAT3: 
441         x = *(float*) curPos;
442         curPos = curPos + sizeof(float);
443         y = *(float*) curPos;
444         curPos = curPos + sizeof(float);
445         z = *(float*) curPos;
446         curPos = curPos + sizeof(float);
447         /**/
448         vshader->input.V[reg].x = x;
449         vshader->input.V[reg].y = y;
450         vshader->input.V[reg].z = z;
451         vshader->input.V[reg].w = 1.0f;
452         break;
453
454       case D3DVSDT_FLOAT4: 
455         x = *(float*) curPos;
456         curPos = curPos + sizeof(float);
457         y = *(float*) curPos;
458         curPos = curPos + sizeof(float);
459         z = *(float*) curPos;
460         curPos = curPos + sizeof(float);
461         w = *(float*) curPos;
462         curPos = curPos + sizeof(float);
463         /**/
464         vshader->input.V[reg].x = x;
465         vshader->input.V[reg].y = y;
466         vshader->input.V[reg].z = z;
467         vshader->input.V[reg].w = w;
468         break;
469
470       case D3DVSDT_D3DCOLOR: 
471         dw = *(DWORD*) curPos;
472         curPos = curPos + sizeof(DWORD);
473         /**/
474         vshader->input.V[reg].x = (float) (((dw >> 16) & 0xFF) / 255.0f);
475         vshader->input.V[reg].y = (float) (((dw >>  8) & 0xFF) / 255.0f);
476         vshader->input.V[reg].z = (float) (((dw >>  0) & 0xFF) / 255.0f);
477         vshader->input.V[reg].w = (float) (((dw >> 24) & 0xFF) / 255.0f);
478         break;
479
480       case D3DVSDT_SHORT2: 
481         u = *(SHORT*) curPos;
482         curPos = curPos + sizeof(SHORT);
483         v = *(SHORT*) curPos;
484         curPos = curPos + sizeof(SHORT);
485         /**/
486         vshader->input.V[reg].x = (float) u;
487         vshader->input.V[reg].y = (float) v;
488         vshader->input.V[reg].z = 0.0f;
489         vshader->input.V[reg].w = 1.0f;
490         break;
491
492       case D3DVSDT_SHORT4: 
493         u = *(SHORT*) curPos;
494         curPos = curPos + sizeof(SHORT);
495         v = *(SHORT*) curPos;
496         curPos = curPos + sizeof(SHORT);
497         r = *(SHORT*) curPos;
498         curPos = curPos + sizeof(SHORT);
499         t = *(SHORT*) curPos;
500         curPos = curPos + sizeof(SHORT);
501         /**/
502         vshader->input.V[reg].x = (float) u;
503         vshader->input.V[reg].y = (float) v;
504         vshader->input.V[reg].z = (float) r;
505         vshader->input.V[reg].w = (float) t;
506         break;
507
508       case D3DVSDT_UBYTE4: 
509         dw = *(DWORD*) curPos;
510         curPos = curPos + sizeof(DWORD);
511         /**/
512         vshader->input.V[reg].x = (float) ((dw & 0x000F) >>  0);
513         vshader->input.V[reg].y = (float) ((dw & 0x00F0) >>  8);
514         vshader->input.V[reg].z = (float) ((dw & 0x0F00) >> 16);
515         vshader->input.V[reg].w = (float) ((dw & 0xF000) >> 24);
516         
517         break;
518
519       default: /** errooooorr what to do ? */
520         ERR("Error in VertexShader declaration of %s register: unsupported type %s\n", VertexShaderDeclRegister[reg], VertexShaderDeclDataTypes[type]);
521       }
522     }
523
524   }
525   /* here D3DVSD_END() */
526   return D3D_OK;
527 }
528
529 HRESULT WINAPI IDirect3DVertexShaderDeclarationImpl_GetDeclaration8(IDirect3DVertexShaderDeclarationImpl* This, DWORD* pData, UINT* pSizeOfData) {
530   if (NULL == pData) {
531     *pSizeOfData = This->declaration8Length;
532     return D3D_OK;
533   }
534   if (*pSizeOfData < This->declaration8Length) {
535     *pSizeOfData = This->declaration8Length;
536     return D3DERR_MOREDATA;
537   }
538   TRACE("(%p) : GetVertexShaderDeclaration copying to %p\n", This, pData);
539   memcpy(pData, This->pDeclaration8, This->declaration8Length);
540   return D3D_OK;
541 }