OSDN Git Service

BGAの表示ずれ、ならびにBGAPAN 時のピクセル揺れを解消。
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / ステージ / 07.演奏 / CAct演奏BGA.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Runtime.InteropServices;\r
5 using System.Drawing;\r
6 using System.Diagnostics;\r
7 using SharpDX.Direct3D9;\r
8 using SharpDX;\r
9 using FDK;\r
10 \r
11 using Point = System.Drawing.Point;\r
12 using Rectangle = System.Drawing.Rectangle;\r
13 \r
14 namespace DTXMania\r
15 {\r
16         internal class CAct演奏BGA : CActivity\r
17         {\r
18                 [StructLayout(LayoutKind.Sequential)]\r
19                 private struct STLAYER\r
20                 {\r
21                         public CDTX.CBMP rBMP;\r
22                         public CDTX.CBMPTEX rBMPTEX;\r
23                         public Size sz開始サイズ;\r
24                         public Size sz終了サイズ;\r
25                         public Point pt画像側開始位置;\r
26                         public Point pt画像側終了位置;\r
27                         public Point pt表示側開始位置;\r
28                         public Point pt表示側終了位置;\r
29                         public long n総移動時間ms;\r
30                         public long n移動開始時刻ms;\r
31                 }\r
32 \r
33                 private CTexture txBGA;\r
34                 private STLAYER[] stLayer = new STLAYER[8];\r
35                 private readonly Size size基準 = new Size( 278, 355 );\r
36 \r
37                 public CAct演奏BGA()\r
38                 {\r
39                         base.b活性化してない = true;\r
40                 }\r
41 \r
42                 public void ChangeScope(CChip chip)\r
43                 {\r
44                         this.stLayer[chip.nBGALayerSwapIndex].rBMP = chip.rBMP;\r
45                         this.stLayer[chip.nBGALayerSwapIndex].rBMPTEX = chip.rBMPTEX;\r
46                 }\r
47 \r
48                 public void Start(CChip chip, CDTX.CBMP bmp, CDTX.CBMPTEX bmptex, int n開始サイズW, int n開始サイズH, int n終了サイズW, int n終了サイズH, int n画像側開始位置X, int n画像側開始位置Y, int n画像側終了位置X, int n画像側終了位置Y, int n表示側開始位置X, int n表示側開始位置Y, int n表示側終了位置X, int n表示側終了位置Y, int n総移動時間ms, int n移動開始時刻ms = -1)\r
49                 {\r
50                         int i = chip.nBGALayerIndex;\r
51                         this.stLayer[i].rBMP = bmp;\r
52                         this.stLayer[i].rBMPTEX = bmptex;\r
53                         this.stLayer[i].sz開始サイズ.Width = n開始サイズW;\r
54                         this.stLayer[i].sz開始サイズ.Height = n開始サイズH;\r
55                         this.stLayer[i].sz終了サイズ.Width = n終了サイズW;\r
56                         this.stLayer[i].sz終了サイズ.Height = n終了サイズH;\r
57                         this.stLayer[i].pt画像側開始位置.X = n画像側開始位置X;\r
58                         this.stLayer[i].pt画像側開始位置.Y = n画像側開始位置Y;\r
59                         this.stLayer[i].pt画像側終了位置.X = n画像側終了位置X;\r
60                         this.stLayer[i].pt画像側終了位置.Y = n画像側終了位置Y;\r
61                         this.stLayer[i].pt表示側開始位置.X = n表示側開始位置X;\r
62                         this.stLayer[i].pt表示側開始位置.Y = n表示側開始位置Y;\r
63                         this.stLayer[i].pt表示側終了位置.X = n表示側終了位置X;\r
64                         this.stLayer[i].pt表示側終了位置.Y = n表示側終了位置Y;\r
65                         this.stLayer[i].n総移動時間ms = n総移動時間ms;\r
66                         this.stLayer[i].n移動開始時刻ms = (n移動開始時刻ms != -1) ? n移動開始時刻ms : CDTXMania.Instance.Timer.n現在時刻;\r
67                 }\r
68 \r
69                 public void SkipStart(int n移動開始時刻ms)\r
70                 {\r
71                         for (int i = 0; i < CDTXMania.Instance.DTX.listChip.Count; i++)\r
72                         {\r
73                                 CChip chip = CDTXMania.Instance.DTX.listChip[i];\r
74                                 if (chip.n発声時刻ms > n移動開始時刻ms)\r
75                                 {\r
76                                         return;\r
77                                 }\r
78                                 switch (chip.eBGA種別)\r
79                                 {\r
80                                         case EBGAType.BMP:\r
81                                                 if ((chip.rBMP != null) && (chip.rBMP.tx画像 != null))\r
82                                                 {\r
83                                                         this.Start(chip, chip.rBMP, null, chip.rBMP.n幅, chip.rBMP.n高さ, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, chip.n発声時刻ms);\r
84                                                 }\r
85                                                 break;\r
86 \r
87                                         case EBGAType.BMPTEX:\r
88                                                 if ((chip.rBMPTEX != null) && (chip.rBMPTEX.tx画像 != null))\r
89                                                 {\r
90                                                         this.Start(chip, null, chip.rBMPTEX, chip.rBMPTEX.tx画像.sz画像サイズ.Width, chip.rBMPTEX.tx画像.sz画像サイズ.Height, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, chip.n発声時刻ms);\r
91                                                 }\r
92                                                 break;\r
93 \r
94                                         case EBGAType.BGA:\r
95                                                 if (chip.rBGA != null)\r
96                                                 {\r
97                                                         this.Start(chip, chip.rBMP, chip.rBMPTEX, chip.rBGA.pt画像側右下座標.X - chip.rBGA.pt画像側左上座標.X, chip.rBGA.pt画像側右下座標.Y - chip.rBGA.pt画像側左上座標.Y, 0, 0, chip.rBGA.pt画像側左上座標.X, chip.rBGA.pt画像側左上座標.Y, 0, 0, chip.rBGA.pt表示座標.X, chip.rBGA.pt表示座標.Y, 0, 0, 0, chip.n発声時刻ms);\r
98                                                 }\r
99                                                 break;\r
100 \r
101                                         case EBGAType.BGAPAN:\r
102                                                 if (chip.rBGAPan != null)\r
103                                                 {\r
104                                                         this.Start(chip, chip.rBMP, chip.rBMPTEX, chip.rBGAPan.sz開始サイズ.Width, chip.rBGAPan.sz開始サイズ.Height, chip.rBGAPan.sz終了サイズ.Width, chip.rBGAPan.sz終了サイズ.Height, chip.rBGAPan.pt画像側開始位置.X, chip.rBGAPan.pt画像側開始位置.Y, chip.rBGAPan.pt画像側終了位置.X, chip.rBGAPan.pt画像側終了位置.Y, chip.rBGAPan.pt表示側開始位置.X, chip.rBGAPan.pt表示側開始位置.Y, chip.rBGAPan.pt表示側終了位置.X, chip.rBGAPan.pt表示側終了位置.Y, chip.n総移動時間, chip.n発声時刻ms);\r
105                                                 }\r
106                                                 break;\r
107                                 }\r
108                         }\r
109                 }\r
110 \r
111                 public void Stop()\r
112                 {\r
113                         for (int i = 0; i < 8; i++)\r
114                         {\r
115                                 this.stLayer[i].n移動開始時刻ms = -1;\r
116                         }\r
117                 }\r
118 \r
119                 public override void On活性化()\r
120                 {\r
121                         for (int i = 0; i < 8; i++)\r
122                         {\r
123                                 STLAYER stlayer2 = new STLAYER();\r
124                                 STLAYER stlayer = stlayer2;\r
125                                 stlayer.rBMP = null;\r
126                                 stlayer.rBMPTEX = null;\r
127                                 stlayer.n移動開始時刻ms = -1;\r
128                                 this.stLayer[i] = stlayer;\r
129                         }\r
130                         base.On活性化();\r
131                 }\r
132 \r
133                 public override void OnManagedリソースの作成()\r
134                 {\r
135                         if (base.b活性化してる)\r
136                         {\r
137                                 using (Surface surface = CDTXMania.Instance.Device.GetBackBuffer(0, 0))\r
138                                 {\r
139                                         try\r
140                                         {\r
141                                                 this.txBGA = new CTexture( CDTXMania.Instance.Device,\r
142                                                         size基準.Width,\r
143                                                         size基準.Height,\r
144                                                         surface.Description.Format,\r
145                                                         Pool.Default,\r
146                                                         Usage.RenderTarget );\r
147 \r
148                                                 txBGA.vc拡大縮小倍率 = new Vector3(\r
149                                                         (float) CDTXMania.Instance.Coordinates.Movie.W / size基準.Width,\r
150                                                         (float) CDTXMania.Instance.Coordinates.Movie.H / size基準.Height,\r
151                                                         1f );\r
152                                         }\r
153                                         catch (Exception e)\r
154                                         {\r
155                                                 Trace.TraceError("CAct演奏BGA: Error: ( " + e.Message + " )");\r
156                                         }\r
157                                 }\r
158                                 base.OnManagedリソースの作成();\r
159                         }\r
160                 }\r
161 \r
162                 public override void OnManagedリソースの解放()\r
163                 {\r
164                         if (base.b活性化してる)\r
165                         {\r
166                                 if (this.txBGA != null)\r
167                                 {\r
168                                         this.txBGA.Dispose();\r
169                                         this.txBGA = null;\r
170                                 }\r
171                                 base.OnManagedリソースの解放();\r
172                         }\r
173                 }\r
174 \r
175                 public override int On進行描画()\r
176                 {\r
177                         if (b活性化してる && CDTXMania.Instance.ConfigIni.bBGA && !CDTXMania.Instance.ConfigIni.bStoicMode)\r
178                         {\r
179                                 // (1) txBGA をレンダーターゲットにして、BGA を描画する。\r
180 \r
181                                 using( Surface sfBackBuffer = CDTXMania.Instance.Device.GetRenderTarget( 0 ) )\r
182                                 {\r
183                                         using( Surface sfBGA = txBGA.texture.GetSurfaceLevel( 0 ) )\r
184                                         {\r
185                                                 CDTXMania.Instance.Device.SetRenderTarget( 0, sfBGA );\r
186                                                 CDTXMania.Instance.Device.Clear( ClearFlags.Target, new ColorBGRA( (int) 0 ), 0f, 0 );\r
187 \r
188                                                 for( int i = 0; i < 8; i++ )\r
189                                                 {\r
190                                                         #region [ レイヤー i の描画 ]\r
191                                                         if( ( ( ( this.stLayer[ i ].n移動開始時刻ms != -1 ) && ( ( this.stLayer[ i ].rBMP != null ) || ( this.stLayer[ i ].rBMPTEX != null ) ) ) ) &&\r
192                                                                 ( ( ( this.stLayer[ i ].rBMP == null ) || ( this.stLayer[ i ].rBMP.bUse && ( this.stLayer[ i ].rBMP.tx画像 != null ) ) ) &&\r
193                                                                 ( ( ( this.stLayer[ i ].rBMPTEX == null ) || ( this.stLayer[ i ].rBMPTEX.bUse && ( this.stLayer[ i ].rBMPTEX.tx画像 != null ) ) ) ) ) )\r
194                                                         {\r
195                                                                 Size sizeStart = this.stLayer[ i ].sz開始サイズ;\r
196                                                                 Size sizeEnd = this.stLayer[ i ].sz終了サイズ;\r
197                                                                 Point ptImgStart = this.stLayer[ i ].pt画像側開始位置;\r
198                                                                 Point ptImgEnd = this.stLayer[ i ].pt画像側終了位置;\r
199                                                                 Point ptDispStart = this.stLayer[ i ].pt表示側開始位置;\r
200                                                                 Point ptDispEnd = this.stLayer[ i ].pt表示側終了位置;\r
201                                                                 long timeTotal = this.stLayer[ i ].n総移動時間ms;\r
202                                                                 long timeMoveStart = this.stLayer[ i ].n移動開始時刻ms;\r
203 \r
204                                                                 if( CDTXMania.Instance.Timer.n現在時刻 < timeMoveStart )\r
205                                                                 {\r
206                                                                         timeMoveStart = CDTXMania.Instance.Timer.n現在時刻;\r
207                                                                 }\r
208 \r
209                                                                 Size sizeBMP = new Size(\r
210                                                                         ( this.stLayer[ i ].rBMP != null ) ? this.stLayer[ i ].rBMP.n幅 : this.stLayer[ i ].rBMPTEX.tx画像.sz画像サイズ.Width,\r
211                                                                         ( this.stLayer[ i ].rBMP != null ) ? this.stLayer[ i ].rBMP.n高さ : this.stLayer[ i ].rBMPTEX.tx画像.sz画像サイズ.Height );\r
212 \r
213                                                                 int n再生位置 = (int) ( ( CDTXMania.Instance.Timer.n現在時刻 - timeMoveStart ) * ( ( (double) CDTXMania.Instance.ConfigIni.nPlaySpeed ) / 20.0 ) );\r
214 \r
215                                                                 if( ( timeTotal != 0 ) && ( timeTotal < n再生位置 ) )\r
216                                                                 {\r
217                                                                         this.stLayer[ i ].pt画像側開始位置 = ptImgStart = ptImgEnd;\r
218                                                                         this.stLayer[ i ].pt表示側開始位置 = ptDispStart = ptDispEnd;\r
219                                                                         this.stLayer[ i ].sz開始サイズ = sizeStart = sizeEnd;\r
220                                                                         this.stLayer[ i ].n総移動時間ms = timeTotal = 0;\r
221                                                                 }\r
222 \r
223                                                                 Rectangle rect画像側 = new Rectangle();\r
224                                                                 Rectangle rect表示側 = new Rectangle();\r
225 \r
226                                                                 if( timeTotal == 0 )\r
227                                                                 {\r
228                                                                         rect画像側.X = ptImgStart.X;\r
229                                                                         rect画像側.Y = ptImgStart.Y;\r
230                                                                         rect画像側.Width = sizeStart.Width;\r
231                                                                         rect画像側.Height = sizeStart.Height;\r
232                                                                         rect表示側.X = ptDispStart.X;\r
233                                                                         rect表示側.Y = ptDispStart.Y;\r
234                                                                         rect表示側.Width = sizeStart.Width;\r
235                                                                         rect表示側.Height = sizeStart.Height;\r
236                                                                 }\r
237                                                                 else\r
238                                                                 {\r
239                                                                         double coefSizeWhileMoving = ( (double) n再生位置 ) / ( (double) timeTotal );\r
240                                                                         Size sizeWhileMoving = new Size( \r
241                                                                                 sizeStart.Width + ( (int) ( ( sizeEnd.Width - sizeStart.Width ) * coefSizeWhileMoving ) ),\r
242                                                                                 sizeStart.Height + ( (int) ( ( sizeEnd.Height - sizeStart.Height ) * coefSizeWhileMoving ) ) );\r
243                                                                         rect画像側.X = ptImgStart.X + ( (int) ( ( ptImgEnd.X - ptImgStart.X ) * coefSizeWhileMoving ) );\r
244                                                                         rect画像側.Y = ptImgStart.Y + ( (int) ( ( ptImgEnd.Y - ptImgStart.Y ) * coefSizeWhileMoving ) );\r
245                                                                         rect画像側.Width = sizeWhileMoving.Width;\r
246                                                                         rect画像側.Height = sizeWhileMoving.Height;\r
247                                                                         rect表示側.X = ptDispStart.X + ( (int) ( ( ptDispEnd.X - ptDispStart.X ) * coefSizeWhileMoving ) );\r
248                                                                         rect表示側.Y = ptDispStart.Y + ( (int) ( ( ptDispEnd.Y - ptDispStart.Y ) * coefSizeWhileMoving ) );\r
249                                                                         rect表示側.Width = sizeWhileMoving.Width;\r
250                                                                         rect表示側.Height = sizeWhileMoving.Height;\r
251                                                                 }\r
252 \r
253                                                                 if(\r
254                                                                         ( rect画像側.Right > 0 ) &&\r
255                                                                         ( rect画像側.Bottom > 0 ) &&\r
256                                                                         ( rect画像側.Left < sizeBMP.Width ) &&\r
257                                                                         ( rect画像側.Top < sizeBMP.Height ) &&\r
258                                                                         ( rect表示側.Right > 0 ) &&\r
259                                                                         ( rect表示側.Bottom > 0 ) &&\r
260                                                                         ( rect表示側.Left < size基準.Width ) &&\r
261                                                                         ( rect表示側.Top < size基準.Height )\r
262                                                                         )\r
263                                                                 {\r
264                                                                         #region " 画像側の表示指定が画像の境界をまたいでいる場合補正 "\r
265                                                                         //----------------\r
266                                                                         if( rect画像側.X < 0 )\r
267                                                                         {\r
268                                                                                 rect表示側.Width -= -rect画像側.X;\r
269                                                                                 rect表示側.X += -rect画像側.X;\r
270                                                                                 rect画像側.Width -= -rect画像側.X;\r
271                                                                                 rect画像側.X = 0;\r
272                                                                         }\r
273                                                                         if( rect画像側.Y < 0 )\r
274                                                                         {\r
275                                                                                 rect表示側.Height -= -rect画像側.Y;\r
276                                                                                 rect表示側.Y += -rect画像側.Y;\r
277                                                                                 rect画像側.Height -= -rect画像側.Y;\r
278                                                                                 rect画像側.Y = 0;\r
279                                                                         }\r
280                                                                         if( rect画像側.Right > sizeBMP.Width )\r
281                                                                         {\r
282                                                                                 rect表示側.Width -= rect画像側.Right - sizeBMP.Width;\r
283                                                                                 rect画像側.Width -= rect画像側.Right - sizeBMP.Width;\r
284                                                                         }\r
285                                                                         if( rect画像側.Bottom > sizeBMP.Height )\r
286                                                                         {\r
287                                                                                 rect表示側.Height -= rect画像側.Bottom - sizeBMP.Height;\r
288                                                                                 rect画像側.Height -= rect画像側.Bottom - sizeBMP.Height;\r
289                                                                         }\r
290                                                                         //----------------\r
291                                                                         #endregion\r
292 \r
293                                                                         #region " 表示側の表示指定が表示域の境界をまたいでいる場合補正 "\r
294                                                                         //----------------\r
295                                                                         if( rect表示側.X < 0 )\r
296                                                                         {\r
297                                                                                 rect画像側.Width -= -rect表示側.X;\r
298                                                                                 rect画像側.X += -rect表示側.X;\r
299                                                                                 rect表示側.Width -= rect表示側.X;\r
300                                                                                 rect表示側.X = 0;\r
301                                                                         }\r
302                                                                         if( rect表示側.Y < 0 )\r
303                                                                         {\r
304                                                                                 rect画像側.Height -= -rect表示側.Y;\r
305                                                                                 rect画像側.Y += -rect表示側.Y;\r
306                                                                                 rect表示側.Height -= -rect表示側.Y;\r
307                                                                                 rect表示側.Y = 0;\r
308                                                                         }\r
309                                                                         if( rect表示側.Right > size基準.Width )\r
310                                                                         {\r
311                                                                                 rect画像側.Width -= rect表示側.Right - size基準.Width;\r
312                                                                                 rect表示側.Width -= rect表示側.Right - size基準.Width;\r
313                                                                         }\r
314                                                                         if( rect表示側.Bottom > size基準.Height )\r
315                                                                         {\r
316                                                                                 rect画像側.Height -= rect表示側.Bottom - size基準.Height;\r
317                                                                                 rect表示側.Height -= rect表示側.Bottom - size基準.Height;\r
318                                                                         }\r
319                                                                         //----------------\r
320                                                                         #endregion\r
321 \r
322                                                                         if(\r
323                                                                                 ( rect画像側.Width > 0 ) &&\r
324                                                                                 ( rect画像側.Height > 0 ) &&\r
325                                                                                 ( rect表示側.Width > 0 ) &&\r
326                                                                                 ( rect表示側.Height > 0 ) &&\r
327 \r
328                                                                                 ( rect画像側.Right >= 0 ) &&\r
329                                                                                 ( rect画像側.Bottom >= 0 ) &&\r
330                                                                                 ( rect画像側.Left <= sizeBMP.Width ) &&\r
331                                                                                 ( rect画像側.Top <= sizeBMP.Height ) &&\r
332                                                                                 ( rect表示側.Right >= 0 ) &&\r
333                                                                                 ( rect表示側.Bottom >= 0 ) &&\r
334                                                                                 ( rect表示側.Left <= size基準.Width ) &&\r
335                                                                                 ( rect表示側.Top <= size基準.Height )\r
336                                                                                 )\r
337                                                                         {\r
338                                                                                 CTexture tex = null;\r
339                                                                                 if( this.stLayer[ i ].rBMP != null )\r
340                                                                                 {\r
341                                                                                         tex = this.stLayer[ i ].rBMP.tx画像;\r
342                                                                                 }\r
343                                                                                 else if( this.stLayer[ i ].rBMPTEX != null )\r
344                                                                                 {\r
345                                                                                         tex = this.stLayer[ i ].rBMPTEX.tx画像;\r
346                                                                                 }\r
347                                                                                 if( tex != null )\r
348                                                                                 {\r
349                                                                                         //if( CDTXMania.Instance.DTX != null && !CDTXMania.Instance.DTX.bUse556x710BGAAVI )\r
350                                                                                         //{\r
351                                                                                         //      tex.vc拡大縮小倍率.X = 2.0f;\r
352                                                                                         //      tex.vc拡大縮小倍率.Y = 2.0f;\r
353                                                                                         //      tex.vc拡大縮小倍率.Z = 1.0f;\r
354                                                                                         //}\r
355 \r
356                                                                                         tex.t2D描画( CDTXMania.Instance.Device, rect表示側.X, rect表示側.Y, rect画像側 );\r
357                                                                                 }\r
358                                                                         }\r
359                                                                 }\r
360                                                         }\r
361                                                         #endregion\r
362                                                 }\r
363 \r
364                                                 // レンダーターゲットをバックバッファに戻す。\r
365                                                 CDTXMania.Instance.Device.SetRenderTarget( 0, sfBackBuffer );\r
366                                         }\r
367                                 }\r
368 \r
369                                 // (2) バックバッファに txBGA を描画する。\r
370 \r
371                                 int x = CDTXMania.Instance.ConfigIni.cdMovieX[ CDTXMania.Instance.ConfigIni.eActiveInst ];\r
372                                 int y = CDTXMania.Instance.ConfigIni.cdMovieY[ CDTXMania.Instance.ConfigIni.eActiveInst ];\r
373 \r
374                                 txBGA.t2D描画( CDTXMania.Instance.Device, x, y );\r
375                         }\r
376                         return 0;\r
377                 }\r
378 \r
379 \r
380         }\r
381 }\r