Project

General

Profile

Download (17.5 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / main / RubikPreRender.java @ 82f42eeb

1 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube 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
// Magic Cube 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 Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 1f9772f3 Leszek Koltunski
package org.distorted.main;
21 8becce57 Leszek Koltunski
22 ccf9fec5 Leszek Koltunski
import android.content.Context;
23 8becce57 Leszek Koltunski
import android.content.SharedPreferences;
24 ccf9fec5 Leszek Koltunski
import android.content.res.Resources;
25 8becce57 Leszek Koltunski
import android.os.Bundle;
26
27 1f9772f3 Leszek Koltunski
import org.distorted.dialogs.RubikDialogNewRecord;
28
import org.distorted.dialogs.RubikDialogSolved;
29
import org.distorted.effects.BaseEffect;
30 8becce57 Leszek Koltunski
import org.distorted.library.message.EffectListener;
31 1f9772f3 Leszek Koltunski
import org.distorted.objects.RubikObject;
32
import org.distorted.objects.RubikObjectList;
33 8becce57 Leszek Koltunski
import org.distorted.scores.RubikScores;
34 1f9772f3 Leszek Koltunski
import org.distorted.states.RubikState;
35
import org.distorted.states.RubikStateSolving;
36 8becce57 Leszek Koltunski
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38
39 5a4d4fba Leszek Koltunski
public class RubikPreRender implements EffectListener
40 8becce57 Leszek Koltunski
  {
41
  public interface ActionFinishedListener
42
    {
43
    void onActionFinished(long effectID);
44
    }
45
46
  private RubikSurfaceView mView;
47 d12bb11b Leszek Koltunski
  private boolean mFinishRotation, mRemoveRotation, mRemovePatternRotation, mAddRotation,
48 4da7d87a Leszek Koltunski
                  mSetQuat, mChangeObject, mSetupObject, mSolveObject, mScrambleObject,
49
                  mInitializeObject, mSetTextureMap, mResetAllTextureMaps;
50 a42e25a6 Leszek Koltunski
  private boolean mCanRotate, mCanPlay;
51 8becce57 Leszek Koltunski
  private boolean mIsSolved;
52
  private RubikObjectList mNextObject;
53
  private int mNextSize;
54
  private long mRotationFinishedID;
55
  private long[] mEffectID;
56
  private boolean mIsNewRecord;
57
  private long mNewRecord;
58
  private int mScreenWidth, mScreenHeight;
59
  private SharedPreferences mPreferences;
60 a31d25de Leszek Koltunski
  private int[][] mNextMoves;
61 8becce57 Leszek Koltunski
  private RubikObject mOldObject, mNewObject;
62
  private int mScrambleObjectNum;
63
  private int mAddRotationAxis, mAddRotationRowBitmap, mAddRotationAngle;
64
  private long mAddRotationDuration;
65
  private ActionFinishedListener mAddActionListener;
66 d12bb11b Leszek Koltunski
  private long mAddRotationID, mRemoveRotationID;
67 1f9772f3 Leszek Koltunski
  private int mCubit, mFace, mNewColor;
68 168b6b56 Leszek Koltunski
  private int mNearestAngle;
69 8becce57 Leszek Koltunski
70
///////////////////////////////////////////////////////////////////////////////////////////////////
71
72 5a4d4fba Leszek Koltunski
  RubikPreRender(RubikSurfaceView view)
73 8becce57 Leszek Koltunski
    {
74
    mView = view;
75
76 d12bb11b Leszek Koltunski
    mFinishRotation       = false;
77
    mRemoveRotation       = false;
78
    mRemovePatternRotation= false;
79
    mAddRotation          = false;
80 4da7d87a Leszek Koltunski
    mSetQuat              = false;
81 d12bb11b Leszek Koltunski
    mChangeObject         = false;
82 2e8ec627 Leszek Koltunski
    mSetupObject          = false;
83 d12bb11b Leszek Koltunski
    mSolveObject          = false;
84
    mScrambleObject       = false;
85 8becce57 Leszek Koltunski
86 a42e25a6 Leszek Koltunski
    mCanRotate = true;
87
    mCanPlay   = true;
88 8becce57 Leszek Koltunski
89
    mOldObject = null;
90
    mNewObject = null;
91
92
    mScreenWidth = mScreenHeight = 0;
93
    mScrambleObjectNum = 0;
94
95
    mEffectID = new long[BaseEffect.Type.LENGTH];
96
    }
97
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
100 a31d25de Leszek Koltunski
  private void createObjectNow(RubikObjectList object, int size, int[][] moves)
101 8becce57 Leszek Koltunski
    {
102
    boolean firstTime = (mNewObject==null);
103
104
    if( mOldObject!=null ) mOldObject.releaseResources();
105
    mOldObject = mNewObject;
106
107 ccf9fec5 Leszek Koltunski
    Context con = mView.getContext();
108
    Resources res = con.getResources();
109
110 5b893eee Leszek Koltunski
    mNewObject = object.create(size, mView.getQuat(), moves, res, mScreenWidth);
111 8becce57 Leszek Koltunski
112 b6d0c697 Leszek Koltunski
    if( mNewObject!=null )
113 8becce57 Leszek Koltunski
      {
114 b6d0c697 Leszek Koltunski
      mNewObject.createTexture();
115
      mView.setMovement(object.getObjectMovementClass());
116 8becce57 Leszek Koltunski
117 b6d0c697 Leszek Koltunski
      if( firstTime ) mNewObject.restorePreferences(mPreferences);
118
119
      if( mScreenWidth!=0 )
120
        {
121
        mNewObject.recomputeScaleFactor(mScreenWidth, mScreenHeight);
122
        }
123
124
      mIsSolved = mNewObject.isSolved();
125
      }
126 8becce57 Leszek Koltunski
    }
127
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129
// do all 'adjustable' effects (SizeChange, Solve, Scramble)
130
131
  private void doEffectNow(BaseEffect.Type type)
132
    {
133
    int index = type.ordinal();
134
135
    try
136
      {
137
      mEffectID[index] = type.startEffect(mView.getRenderer().getScreen(),this);
138
      }
139
    catch( Exception ex )
140
      {
141
      android.util.Log.e("renderer", "exception starting effect: "+ex.getMessage());
142
143 a42e25a6 Leszek Koltunski
      mCanPlay   = true;
144 8becce57 Leszek Koltunski
      mCanRotate = true;
145
      }
146
    }
147
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149
150
  private void removeRotationNow()
151
    {
152
    mRemoveRotation=false;
153
    mNewObject.removeRotationNow();
154
155
    boolean solved = mNewObject.isSolved();
156
157
    if( solved && !mIsSolved )
158
      {
159
      if( RubikState.getCurrentState()==RubikState.SOLV )
160
        {
161
        RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass();
162 1f894991 Leszek Koltunski
        mNewRecord = solving.getRecord();
163 8becce57 Leszek Koltunski
164
        if( mNewRecord< 0 )
165
          {
166
          mNewRecord = -mNewRecord;
167
          mIsNewRecord = false;
168
          }
169
        else
170
          {
171
          mIsNewRecord = true;
172
          }
173
        }
174
175 1019cc43 Leszek Koltunski
      mCanRotate = true;
176 a42e25a6 Leszek Koltunski
      mCanPlay = false;
177 8becce57 Leszek Koltunski
      doEffectNow( BaseEffect.Type.WIN );
178
      }
179
    else
180
      {
181
      mCanRotate = true;
182 a42e25a6 Leszek Koltunski
      mCanPlay = true;
183 8becce57 Leszek Koltunski
      }
184
185
    mIsSolved = solved;
186
    }
187
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
190
  private void removeRotation()
191
    {
192
    mRemoveRotation = true;
193
    }
194
195 d12bb11b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
196
197
  private void removePatternRotation()
198
    {
199
    mRemovePatternRotation = true;
200
    }
201
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203
204
  private void removePatternRotationNow()
205
    {
206
    mRemovePatternRotation=false;
207
    mNewObject.removeRotationNow();
208
    mAddActionListener.onActionFinished(mRemoveRotationID);
209
    }
210
211 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
212
213
  private void addRotationNow()
214
    {
215
    mAddRotation = false;
216
    mAddRotationID = mNewObject.addNewRotation( mAddRotationAxis, mAddRotationRowBitmap,
217
                                                mAddRotationAngle, mAddRotationDuration, this);
218
    }
219
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221
222
  private void finishRotationNow()
223
    {
224
    mFinishRotation = false;
225
    mCanRotate      = false;
226 a42e25a6 Leszek Koltunski
    mCanPlay        = false;
227 168b6b56 Leszek Koltunski
    mRotationFinishedID = mNewObject.finishRotationNow(this, mNearestAngle);
228 8becce57 Leszek Koltunski
229
    if( mRotationFinishedID==0 ) // failed to add effect - should never happen
230
      {
231
      mCanRotate = true;
232 a42e25a6 Leszek Koltunski
      mCanPlay   = true;
233 8becce57 Leszek Koltunski
      }
234
    }
235
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237
238
  private void changeObjectNow()
239
    {
240
    mChangeObject = false;
241
242 2e8ec627 Leszek Koltunski
    if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
243
      {
244
      mCanRotate= false;
245
      mCanPlay  = false;
246
      createObjectNow(mNextObject, mNextSize, null);
247
      doEffectNow( BaseEffect.Type.SIZECHANGE );
248
      }
249
    }
250
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252
253
  private void setupObjectNow()
254
    {
255
    mSetupObject = false;
256
257 8becce57 Leszek Koltunski
    if ( mNewObject==null || mNewObject.getObjectList()!=mNextObject || mNewObject.getSize()!=mNextSize)
258
      {
259 a42e25a6 Leszek Koltunski
      mCanRotate= false;
260
      mCanPlay  = false;
261 8becce57 Leszek Koltunski
      createObjectNow(mNextObject, mNextSize, mNextMoves);
262
      doEffectNow( BaseEffect.Type.SIZECHANGE );
263
      }
264
    else
265
      {
266
      mNewObject.initializeObject(mNextMoves);
267
      }
268
    }
269
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271
272
  private void scrambleObjectNow()
273
    {
274
    mScrambleObject = false;
275
    mCanRotate      = false;
276 a42e25a6 Leszek Koltunski
    mCanPlay        = false;
277 8becce57 Leszek Koltunski
    mIsSolved       = false;
278
    RubikScores.getInstance().incrementNumPlays();
279
    doEffectNow( BaseEffect.Type.SCRAMBLE );
280
    }
281
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283
284
  private void solveObjectNow()
285
    {
286 a42e25a6 Leszek Koltunski
    mSolveObject = false;
287
    mCanRotate   = false;
288
    mCanPlay     = false;
289 8becce57 Leszek Koltunski
    doEffectNow( BaseEffect.Type.SOLVE );
290
    }
291
292 d12bb11b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294
  private void initializeObjectNow()
295
    {
296
    mInitializeObject = false;
297
    mNewObject.initializeObject(mNextMoves);
298
    }
299
300 1f9772f3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
301
302
  private void setTextureMapNow()
303
    {
304
    mSetTextureMap = false;
305
306 b6d0c697 Leszek Koltunski
    if( mNewObject!=null ) mNewObject.setTextureMap(mCubit,mFace,mNewColor);
307 1f9772f3 Leszek Koltunski
    }
308
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310
311
  private void resetAllTextureMapsNow()
312
    {
313
    mResetAllTextureMaps = false;
314
315 b6d0c697 Leszek Koltunski
    if( mNewObject!=null ) mNewObject.resetAllTextureMaps();
316 1f9772f3 Leszek Koltunski
    }
317
318 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
319
320 4da7d87a Leszek Koltunski
  private void setQuatNow()
321 8becce57 Leszek Koltunski
    {
322 4da7d87a Leszek Koltunski
    mSetQuat = false;
323
    mView.setQuat();
324 8becce57 Leszek Koltunski
    }
325
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327
//
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329
330
  void setScreenSize(int width, int height)
331
    {
332
    if( mNewObject!=null )
333
      {
334
      mNewObject.createTexture();
335
      mNewObject.recomputeScaleFactor(width,height);
336
      }
337
338
    mScreenHeight = height;
339
    mScreenWidth  = width;
340
    }
341
342
///////////////////////////////////////////////////////////////////////////////////////////////////
343
344
  void savePreferences(SharedPreferences.Editor editor)
345
    {
346
    if( mNewObject!=null )
347
      {
348
      mNewObject.savePreferences(editor);
349
      }
350
    }
351
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353
354
  void restorePreferences(SharedPreferences preferences)
355
    {
356
    mPreferences = preferences;
357
    }
358
359
///////////////////////////////////////////////////////////////////////////////////////////////////
360
361 168b6b56 Leszek Koltunski
  void finishRotation(int nearestAngle)
362 8becce57 Leszek Koltunski
    {
363 168b6b56 Leszek Koltunski
    mNearestAngle   = nearestAngle;
364 8becce57 Leszek Koltunski
    mFinishRotation = true;
365
    }
366
367
///////////////////////////////////////////////////////////////////////////////////////////////////
368
369 2e8ec627 Leszek Koltunski
  void changeObject(RubikObjectList object, int size)
370 8becce57 Leszek Koltunski
    {
371
    if( size>0 )
372
      {
373
      mChangeObject = true;
374
      mNextObject = object;
375
      mNextSize   = size;
376 2e8ec627 Leszek Koltunski
      }
377
    }
378
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380
381
  void setupObject(RubikObjectList object, int size, int[][] moves)
382
    {
383
    if( size>0 )
384
      {
385
      mSetupObject= true;
386
      mNextObject = object;
387
      mNextSize   = size;
388 8becce57 Leszek Koltunski
      mNextMoves  = moves;
389
      }
390
    }
391
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393
394 85b09df4 Leszek Koltunski
  void setTextureMap(int cubit, int face, int newColor)
395 8becce57 Leszek Koltunski
    {
396 85b09df4 Leszek Koltunski
    mSetTextureMap = true;
397 8becce57 Leszek Koltunski
398 85b09df4 Leszek Koltunski
    mCubit    = cubit;
399
    mFace     = face;
400
    mNewColor = newColor;
401 8becce57 Leszek Koltunski
    }
402
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404
405
  boolean canRotate()
406
    {
407
    return mCanRotate;
408
    }
409
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411
412 a42e25a6 Leszek Koltunski
  public boolean canPlay()
413 8becce57 Leszek Koltunski
    {
414 a42e25a6 Leszek Koltunski
    return mCanPlay;
415 8becce57 Leszek Koltunski
    }
416
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418
419 4da7d87a Leszek Koltunski
  void setQuatOnNextRender()
420 8becce57 Leszek Koltunski
    {
421 4da7d87a Leszek Koltunski
    mSetQuat = true;
422 8becce57 Leszek Koltunski
    }
423
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425
426 5a4d4fba Leszek Koltunski
  void preRender()
427 8becce57 Leszek Koltunski
    {
428 4da7d87a Leszek Koltunski
    if( mSetQuat               ) setQuatNow();
429 d12bb11b Leszek Koltunski
    if( mFinishRotation        ) finishRotationNow();
430
    if( mRemoveRotation        ) removeRotationNow();
431
    if( mRemovePatternRotation ) removePatternRotationNow();
432
    if( mChangeObject          ) changeObjectNow();
433 2e8ec627 Leszek Koltunski
    if( mSetupObject           ) setupObjectNow();
434 d12bb11b Leszek Koltunski
    if( mSolveObject           ) solveObjectNow();
435
    if( mScrambleObject        ) scrambleObjectNow();
436
    if( mAddRotation           ) addRotationNow();
437
    if( mInitializeObject      ) initializeObjectNow();
438 1f9772f3 Leszek Koltunski
    if( mResetAllTextureMaps   ) resetAllTextureMapsNow();
439
    if( mSetTextureMap         ) setTextureMapNow();
440 8becce57 Leszek Koltunski
    }
441
442
///////////////////////////////////////////////////////////////////////////////////////////////////
443
// PUBLIC API
444
///////////////////////////////////////////////////////////////////////////////////////////////////
445
446
  public void addRotation(ActionFinishedListener listener, int axis, int rowBitmap, int angle, long duration)
447
    {
448
    mAddRotation = true;
449
450
    mAddActionListener    = listener;
451
    mAddRotationAxis      = axis;
452
    mAddRotationRowBitmap = rowBitmap;
453
    mAddRotationAngle     = angle;
454
    mAddRotationDuration  = duration;
455
    }
456
457 d12bb11b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
458
459
  public void initializeObject(int[][] moves)
460
    {
461
    mInitializeObject = true;
462
    mNextMoves = moves;
463
    }
464
465 1f9772f3 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
466
467 85b09df4 Leszek Koltunski
  public void scrambleObject(int num)
468 1f9772f3 Leszek Koltunski
    {
469 85b09df4 Leszek Koltunski
    if( mCanPlay )
470
      {
471
      mScrambleObject = true;
472
      mScrambleObjectNum = num;
473
      }
474
    }
475 1f9772f3 Leszek Koltunski
476 85b09df4 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
477
478
  public void solveObject()
479
    {
480
    if( mCanPlay )
481
      {
482
      mSolveObject = true;
483
      }
484 1f9772f3 Leszek Koltunski
    }
485
486
///////////////////////////////////////////////////////////////////////////////////////////////////
487
488
  public void resetAllTextureMaps()
489
    {
490
    mResetAllTextureMaps = true;
491
    }
492
493 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
494
495
  public RubikObject getObject()
496
    {
497
    return mNewObject;
498
    }
499
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501
502
  public RubikObject getOldObject()
503
    {
504
    return mOldObject;
505
    }
506
507
///////////////////////////////////////////////////////////////////////////////////////////////////
508
509
  public int getNumScrambles()
510
    {
511
    return mScrambleObjectNum;
512
    }
513
514
///////////////////////////////////////////////////////////////////////////////////////////////////
515
516
  public void effectFinished(final long effectID)
517
    {
518
    if( effectID == mRotationFinishedID )
519
      {
520
      mRotationFinishedID = 0;
521
      removeRotation();
522
      }
523
    else if( effectID == mAddRotationID )
524
      {
525
      mAddRotationID = 0;
526 d12bb11b Leszek Koltunski
      mRemoveRotationID = effectID;
527
      removePatternRotation();
528 8becce57 Leszek Koltunski
      }
529
    else
530
      {
531
      for(int i=0; i<BaseEffect.Type.LENGTH; i++)
532
        {
533
        if( effectID == mEffectID[i] )
534
          {
535 a42e25a6 Leszek Koltunski
          mCanRotate = true;
536
          mCanPlay   = true;
537 8becce57 Leszek Koltunski
538
          if( i==BaseEffect.Type.SCRAMBLE.ordinal() )
539
            {
540
            final RubikActivity act = (RubikActivity)mView.getContext();
541
542
            act.runOnUiThread(new Runnable()
543
              {
544
              @Override
545
              public void run()
546
                {
547 807d82b7 Leszek Koltunski
                RubikState.switchState( act, RubikState.READ);
548 8becce57 Leszek Koltunski
                }
549
              });
550
            }
551
552
          if( i==BaseEffect.Type.WIN.ordinal() )
553
            {
554
            if( RubikState.getCurrentState()==RubikState.SOLV )
555
              {
556
              final RubikActivity act = (RubikActivity)mView.getContext();
557
              Bundle bundle = new Bundle();
558
              bundle.putLong("time", mNewRecord );
559
560
              if( mIsNewRecord )
561
                {
562
                RubikDialogNewRecord dialog = new RubikDialogNewRecord();
563
                dialog.setArguments(bundle);
564
                dialog.show( act.getSupportFragmentManager(), null);
565
                }
566
              else
567
                {
568
                RubikDialogSolved dialog = new RubikDialogSolved();
569
                dialog.setArguments(bundle);
570
                dialog.show( act.getSupportFragmentManager(), null);
571
                }
572 807d82b7 Leszek Koltunski
573
              act.runOnUiThread(new Runnable()
574
                {
575
                @Override
576
                public void run()
577
                  {
578
                  RubikState.switchState( act, RubikState.DONE);
579
                  }
580
                });
581 8becce57 Leszek Koltunski
              }
582
            }
583
584
          break;
585
          }
586
        }
587
      }
588
    }
589
  }