home *** CD-ROM | disk | FTP | other *** search
/ MORE WinGames / WINGAMES.iso / winjig / jigsaw.txt < prev    next >
Text File  |  1991-05-30  |  22KB  |  676 lines

  1. DefInt A-Z
  2.  
  3. Declare Function BitBlt Lib "Gdi" (ByVal destHdc, ByVal X, ByVal Y, ByVal w, ByVal h, ByVal srcHdc, ByVal srcX, ByVal srcY, ByVal Rop As Long)
  4. Declare Function CreateRectRgn Lib "Gdi" (ByVal X1, ByVal Y1, ByVal X2, ByVal Y2)
  5. Declare Function SetRectRgn Lib "Gdi" (ByVal hRgn, ByVal X1, ByVal Y1, ByVal X2, ByVal Y2)
  6. Declare Function SelectClipRgn Lib "Gdi" (ByVal Hdc, ByVal hRgn)
  7. Declare Function CombineRgn Lib "Gdi" (ByVal hDestRgn, ByVal hSrcRgn1, ByVal hSrcRgn2, ByVal nCombineMode)
  8.  
  9. Const SRCCOPY = &HCC0020
  10. Const SRCAND = &H8800C6
  11. Const SRCINVERT = &H660046
  12. Const NOTSRCCOPY = &H330008
  13. Const SRCINVERTANDDEST = &H220B24
  14.  
  15. Const RGN_AND = 1
  16. Const RGN_DIFF = 4
  17. Const NULLREGION = 1
  18.  
  19. Const TRUE = -1
  20. Const FALSE = 0
  21. Const MODAL = 1
  22.  
  23. Const MID_OPEN = 0
  24. Const MID_CLIPBOARD = 1
  25. Const MID_EXIT = 3
  26.  
  27. Const MID_SCRAMMBLE = 0
  28. Const MID_SOLVE = 1
  29. Const MID_ANIMATE = 2
  30. Const MID_PIECES_TO_FOREGROUND = 3
  31. Const MID_SHOW_SCRAMMBLING = 5
  32. Const MID_SCRAMMBLE_ON_OPEN = 6
  33.  
  34. Const MID_CIRCLES_AND_OTHERS = 1
  35. Const MID_ELIPSES_AND_OTHERS = 2
  36. Const MID_ANGELS_AND_STARS = 3
  37. Const MID_CIRCLES_IN_SQUARES = 4
  38.  
  39. Dim TotalPieces  As Integer
  40. Dim PuzzleSize   As Integer
  41. Dim PieceHeight  As Integer
  42. Dim PieceWidth   As Integer
  43. Dim MovingPiece  As Integer
  44. Dim LastMouseX   As Integer
  45. Dim LastMouseY   As Integer
  46. Dim MaskNeeded   As Integer
  47. Dim Solved       As Integer
  48.  
  49. Dim Region1 As Integer
  50. Dim Region2 As Integer
  51. Dim Region3 As Integer
  52. Dim Region4 As Integer
  53.  
  54. Dim Piece As PIECEINFO
  55. Dim Pieces() As PIECEINFO
  56. Dim Priority() As Integer
  57.  
  58.  
  59. Sub Form_Load ()
  60.  
  61.     Region1 = CreateRectRgn(0, 0, 0, 0)
  62.     Region2 = CreateRectRgn(0, 0, 0, 0)
  63.     Region3 = CreateRectRgn(0, 0, 0, 0)
  64.     Region4 = CreateRectRgn(0, 0, 0, 0)
  65.  
  66.     PuzzleSize = 5
  67.  
  68.     Menu_Stop.Visible = FALSE
  69.  
  70. End Sub
  71.  
  72. Sub Set_Piece_Priority (Piece As Integer)
  73.  
  74.     Temp = Priority(Piece)
  75.     For I = Piece To 1 Step -1
  76.         Priority(I) = Priority(I - 1)
  77.     Next
  78.     Priority(0) = Temp
  79.  
  80. End Sub
  81.  
  82. Sub Display_A_Piece (destHdc, Piece)
  83.     
  84.     DestX = Pieces(Priority(Piece)).X
  85.     DestY = Pieces(Priority(Piece)).Y
  86.     
  87.     If MaskNeeded Then
  88.         R = BitBlt(Pic_FinalPiece.Hdc, 0, 0, PieceWidth, PieceHeight, Pic_PuzzleImage.Hdc, DestX, DestY, SRCCOPY)
  89.         R = BitBlt(Pic_FinalPiece.Hdc, 0, 0, PieceWidth, PieceHeight, Pic_PieceMask.Hdc, 0, 0, SRCAND)
  90.         R = BitBlt(Pic_FinalPiece.Hdc, 0, 0, PieceWidth, PieceHeight, Pic_PieceImage.Hdc, 0, 0, SRCINVERT)
  91.         R = BitBlt(destHdc, DestX, DestY, PieceWidth, PieceHeight, Pic_FinalPiece.Hdc, 0, 0, SRCCOPY)
  92.     Else
  93.         R = BitBlt(destHdc, DestX, DestY, PieceWidth, PieceHeight, Pic_Bitmap.Hdc, Pieces(Priority(Piece)).HomeX, Pieces(Priority(Piece)).HomeY, SRCCOPY)
  94.     End If
  95.  
  96. End Sub
  97.  
  98.  
  99. Sub Menu_OptionsSelection_Click (Index As Integer)
  100.  
  101.     Pic_Work.MousePointer = 11
  102.  
  103.     Select Case Index
  104.         
  105.         Case MID_SCRAMMBLE
  106.             Scrammble_Puzzle
  107.  
  108.         Case MID_SOLVE
  109.             Solve_Puzzle
  110.  
  111.         Case MID_ANIMATE
  112.             Animate_Puzzle
  113.         
  114.         Case MID_PIECES_TO_FOREGROUND
  115.             Bring_Pieces_To_Foreground
  116.  
  117.         Case MID_SHOW_SCRAMMBLING, MID_SCRAMMBLE_ON_OPEN
  118.             Menu_OptionsSelection(Index).Checked = Not Menu_OptionsSelection(Index).Checked
  119.  
  120.     End Select
  121.  
  122.     Pic_Work.MousePointer = 0
  123.     
  124. End Sub
  125.  
  126. Sub Menu_FileSelection_Click (Index As Integer)
  127.  
  128.     Picture = LoadPicture()
  129.  
  130.     Select Case Index
  131.  
  132.         Case MID_OPEN
  133.             OpenFile.Show MODAL
  134.             If OpenFile.File1.ListIndex >= 0 Then Picture = LoadPicture(OpenFile.File1.FileName)
  135.  
  136.         Case MID_CLIPBOARD
  137.             Picture = ClipBoard.GetData()
  138.  
  139.         Case MID_EXIT
  140.             Unload JigSaw
  141.  
  142.     End Select
  143.  
  144.     If Picture Then
  145.         Menu_Options.Enabled = TRUE
  146.         Menu_Pieces.Enabled = TRUE
  147.         Menu_Hint.Enabled = TRUE
  148.         Pic_Work.Visible = TRUE
  149.         Screen.MousePointer = 11
  150.         Prepare_Bitmap (Menu_OptionsSelection(MID_SCRAMMBLE_ON_OPEN).Checked)
  151.         Screen.MousePointer = 0
  152.         Pic_Window.Refresh
  153.     End If
  154.  
  155. End Sub
  156.  
  157. Sub Prepare_Bitmap (Scrammble)
  158.             
  159.     Pic_Bitmap.Picture = Picture
  160.     Pic_Bitmap.Picture = Pic_Bitmap.Image
  161.  
  162.     PieceWidth = Pic_Bitmap.Width / PuzzleSize
  163.     PieceHeight = Pic_Bitmap.Height / PuzzleSize
  164.  
  165.     Pic_PuzzleImage.Cls
  166.     Pic_PuzzleImage.Move 0, 0, Pic_Bitmap.Width, Pic_Bitmap.Height
  167.     Pic_Work.Move 0, 0, Pic_Bitmap.Width, Pic_Bitmap.Height
  168.     Pic_Mask.Move 0, 0, Pic_Bitmap.Width, Pic_Bitmap.Height
  169.     Pic_Mask.Cls
  170.  
  171.     Form_Resize
  172.     Randomize Timer
  173.     TotalPieces = 24
  174.  
  175.     If MaskNeeded Then
  176.         
  177.         Pic_PieceImage.Move 0, 0, PieceWidth, PieceHeight
  178.         Pic_PieceMask.Move 0, 0, PieceWidth, PieceHeight
  179.         Pic_FinalPiece.Move 0, 0, PieceWidth, PieceHeight
  180.         
  181.         Select Case MaskNeeded
  182.             
  183.             Case MID_CIRCLES_AND_OTHERS
  184.                 Create_Circles_Mask
  185.  
  186.             Case MID_ELIPSES_AND_OTHERS
  187.                 Create_Elipses_Mask
  188.  
  189.             Case MID_ANGELS_AND_STARS
  190.                 Create_Angel_And_Stars_Mask
  191.  
  192.             Case MID_CIRCLES_IN_SQUARES
  193.                 TotalPieces = 31
  194.                 Create_Circles_In_Squares_Mask
  195.  
  196.         End Select
  197.     End If
  198.     
  199.     ReDim Pieces(TotalPieces) As PIECEINFO
  200.     ReDim Priority(TotalPieces) As Integer
  201.  
  202.     If (MaskNeeded > 0) And (MaskNeeded <> MID_CIRCLES_IN_SQUARES) Then
  203.         For Y = 0 To PuzzleSize - 2
  204.             For X = 0 To PuzzleSize - 2
  205.                 I = TotalPieces - (Y * (PuzzleSize - 1) + X)
  206.                 Pieces(I).HomeX = X * PieceWidth + PieceWidth / 2
  207.                 Pieces(I).HomeY = Y * PieceHeight + PieceHeight / 2
  208.                 Pieces(I).X = Pieces(I).HomeX
  209.                 Pieces(I).Y = Pieces(I).HomeY
  210.                 Priority(I) = I
  211.             Next X
  212.         Next Y
  213.     End If
  214.  
  215.     For Y = 0 To PuzzleSize - 1
  216.         For X = 0 To PuzzleSize - 1
  217.             I = (PuzzleSize ^ 2 - 1) - (Y * PuzzleSize + X)
  218.             For Z = 0 To Abs(MaskNeeded = MID_CIRCLES_IN_SQUARES)
  219.                 Pieces(I + Z * 16).HomeX = X * PieceWidth
  220.                 Pieces(I + Z * 16).HomeY = Y * PieceHeight
  221.                 Pieces(I + Z * 16).X = Pieces(I).HomeX
  222.                 Pieces(I + Z * 16).Y = Pieces(I).HomeY
  223.                 Priority(I + Z * 16) = I + Z * 16
  224.             Next Z
  225.         Next X
  226.     Next Y
  227.     
  228.     Select Case MaskNeeded
  229.         Case 0, 4
  230.             Outline_Circles_In_Squares
  231.         Case 1
  232.         Case 2
  233.         Case 3
  234.     End Select
  235.  
  236.     If Scrammble Then
  237.         Scrammble_Puzzle
  238.     Else
  239.         Solved = TRUE
  240.         R = BitBlt(Pic_PuzzleImage.Hdc, 0, 0, Pic_Bitmap.Width, Pic_Bitmap.Height, Pic_Bitmap.Hdc, 0, 0, SRCCOPY)
  241.         Pic_Work.Refresh
  242.     End If
  243.     
  244. End Sub
  245.  
  246. Sub Form_Unload (Cancel As Integer)
  247.  
  248.     End
  249.  
  250. End Sub
  251.  
  252. Sub Form_Resize ()
  253.  
  254.     Pic_Work.Move 0, 0
  255.     
  256.     HScroll1.Move 0, ScaleHeight - HScroll1.Height, ScaleWidth - VScroll1.Width
  257.     VScroll1.Move ScaleWidth - VScroll1.Width, 0, VScroll1.Width, ScaleHeight - HScroll1.Height
  258.     Pic_ScrollBarJoint.Move VScroll1.Left, HScroll1.Top
  259.     Pic_Window.Move 0, 0, VScroll1.Left, HScroll1.Top
  260.  
  261.     HScroll1.Enabled = Pic_Window.Width < Pic_Bitmap.Width
  262.     VScroll1.Enabled = Pic_Window.Height < Pic_Bitmap.Height
  263.     
  264.     If VScroll1.Enabled Then
  265.         VScroll1.Value = 0
  266.         VScroll1.Max = Abs(Pic_Window.Height - Pic_Bitmap.Height)
  267.         VScroll1.LargeChange = VScroll1.Max \ 10
  268.     End If
  269.     
  270.     If HScroll1.Enabled Then
  271.         HScroll1.Value = 0
  272.         HScroll1.Max = Abs(Pic_Window.Width - Pic_Bitmap.Width)
  273.         HScroll1.LargeChange = HScroll1.Max \ 10
  274.     End If
  275.     
  276. End Sub
  277.  
  278. Sub HScroll1_Change ()
  279.   
  280.   ' Pic_Work.Left is set to the Negative of the value since
  281.   ' as you scroll the Scrollbar to the Right, the display
  282.   ' should move to the Left, showing more of the right
  283.   ' of the display, and vice-versa when scrolling to the
  284.   ' left
  285.  
  286.   Pic_Work.Left = -HScroll1.Value
  287.  
  288. End Sub
  289.  
  290. Sub VScroll1_Change ()
  291.   
  292.   ' Pic_Work.Top is set to the Negative of the value since
  293.   ' as you scroll the Scrollbar down, the display
  294.   ' should move up, showing more of the the bottom
  295.   ' of the display, and vice-versa when scrolling up
  296.   
  297.   Pic_Work.Top = -VScroll1.Value
  298.   
  299. End Sub
  300.  
  301. Sub Pic_Work_MouseMove (Button As Integer, Shift As Integer, X As Single, Y As Single)
  302.  
  303.     If MovingPiece And (Not Menu_Stop.Visible) Then Move_Piece X + 0, Y + 0
  304.  
  305. End Sub
  306.  
  307. Sub Pic_Work_MouseUp (Button As Integer, Shift As Integer, X As Single, Y As Single)
  308.  
  309.     If MovingPiece And (Not Menu_Stop.Visible) Then
  310.         
  311.         If CombineRgn(Region3, Region4, Region2, RGN_AND) <> NULLREGION Then
  312.             R = BitBlt(Pic_Work.Hdc, Pieces(Priority(0)).X, Pieces(Priority(0)).Y, PieceWidth, PieceHeight, Pic_PuzzleImage.Hdc, Pieces(Priority(0)).X, Pieces(Priority(0)).Y, SRCCOPY)
  313.             Pieces(Priority(0)).X = Pieces(Priority(I)).HomeX
  314.             Pieces(Priority(0)).Y = Pieces(Priority(I)).HomeY
  315.             Display_A_Piece (Pic_Work.Hdc), 0
  316.             Beep
  317.         End If
  318.         Display_A_Piece (Pic_PuzzleImage.Hdc), 0
  319.  
  320.         For I = 0 To TotalPieces
  321.             If (Pieces(I).X <> Pieces(I).HomeX) Or (Pieces(I).Y <> Pieces(I).HomeY) Then Exit For
  322.         Next
  323.         If I > TotalPieces Then
  324.             Restore_Bitmap
  325.             MsgBox "You have solved the puzzle", 16, "VB JigSaw"
  326.         End If
  327.         Menu_Hint.Enabled = (Pieces(Priority(0)).X <> Pieces(Priority(0)).HomeX) Or (Pieces(Priority(0)).Y <> Pieces(Priority(0)).HomeY)
  328.         
  329.     End If
  330.     MovingPiece = FALSE
  331.     Pic_Work.MousePointer = 0
  332.  
  333. End Sub
  334.  
  335. Sub Pic_Work_MouseDown (Button As Integer, Shift As Integer, X As Single, Y As Single)
  336.  
  337.     If (Button = 1) And (Not Menu_Stop.Visible) Then
  338.         If Solved Then
  339.             Solved = FALSE
  340.             Pic_PuzzleImage.Picture = Pic_Bitmap.Image
  341.             Pic_Work_Paint
  342.         End If
  343.         For I = 0 To TotalPieces
  344.             Piece = Pieces(Priority(I))
  345.             If (X >= Piece.X) And (X <= Piece.X + PieceWidth - 1) Then
  346.                 If (Y >= Piece.Y) And (Y <= Piece.Y + PieceHeight - 1) Then
  347.                     If Pic_Mask.Point(Piece.HomeX + (X - Piece.X), Piece.HomeY + (Y - Piece.Y)) = (Priority(I) < (PuzzleSize ^ 2) And &HFFFFFF) Then
  348.                         Set_Piece_Priority I
  349.                         Prepare_To_Move_Piece X + 0, Y + 0
  350.                         Pic_Work.MousePointer = 5
  351.                         Exit For
  352.                     End If
  353.                 End If
  354.             End If
  355.         Next I
  356.     ElseIf (Button = 2) And Solved Then
  357.         Pic_PuzzleImage.Picture = Pic_Bitmap.Image
  358.         Pic_Work_Paint
  359.     End If
  360.  
  361. End Sub
  362.  
  363. Sub Pic_Work_Paint ()
  364.  
  365.     R = BitBlt(Pic_Work.Hdc, 0, 0, Pic_Bitmap.Width, Pic_Bitmap.Height, Pic_PuzzleImage.Hdc, 0, 0, SRCCOPY)
  366.  
  367. End Sub
  368.  
  369. Sub Menu_PiecesSelection_Click (Index As Integer)
  370.  
  371.     Menu_PiecesSelection(MaskNeeded).Checked = FALSE
  372.     Menu_PiecesSelection(Index).Checked = TRUE
  373.     MaskNeeded = Index
  374.     If MaskNeeded Then PuzzleSize = 4 Else PuzzleSize = 5
  375.     Prepare_Bitmap TRUE
  376.         
  377. End Sub
  378.  
  379. Sub Menu_Stop_Click ()
  380.  
  381.     Menu_File.Enabled = TRUE
  382.     Menu_Options.Enabled = TRUE
  383.     Menu_Pieces.Enabled = TRUE
  384.     Menu_Hint.Enabled = TRUE
  385.     Menu_Stop.Visible = FALSE
  386.  
  387. End Sub
  388.  
  389. Sub Move_Piece (X, Y)
  390.         
  391.     LastX = Pieces(Priority(0)).X
  392.     LastY = Pieces(Priority(0)).Y
  393.  
  394.     Pieces(Priority(0)).X = Pieces(Priority(0)).X + (X - LastMouseX)
  395.     Pieces(Priority(0)).Y = Pieces(Priority(0)).Y + (Y - LastMouseY)
  396.     Display_A_Piece (Pic_Work.Hdc), 0
  397.  
  398.     R = SetRectRgn(Region1, LastX, LastY, LastX + PieceWidth, LastY + PieceHeight)
  399.     R = SetRectRgn(Region2, Pieces(Priority(0)).X, Pieces(Priority(0)).Y, Pieces(Priority(0)).X + PieceWidth, Pieces(Priority(0)).Y + PieceHeight)
  400.     R = CombineRgn(Region3, Region1, Region2, RGN_DIFF)
  401.     R = SelectClipRgn(Pic_Work.Hdc, Region3)
  402.     R = BitBlt(Pic_Work.Hdc, LastX, LastY, PieceWidth, PieceHeight, Pic_PuzzleImage.Hdc, LastX, LastY, SRCCOPY)
  403.     R = SelectClipRgn(Pic_Work.Hdc, 0)
  404.  
  405.     LastMouseX = X
  406.     LastMouseY = Y
  407.  
  408. End Sub
  409.  
  410. Sub Prepare_To_Move_Piece (X, Y)
  411.     
  412.     Piece = Pieces(Priority(0))
  413.     If MaskNeeded Then Get_Mask_And_Image 0
  414.     Display_A_Piece (Pic_Work.Hdc), 0
  415.                     
  416.     R = SetRectRgn(Region2, Piece.X, Piece.Y, Piece.X + PieceWidth, Piece.Y + PieceHeight)
  417.     R = SelectClipRgn(Pic_PuzzleImage.Hdc, Region2)
  418.     Pic_PuzzleImage.Line (Piece.X, Piece.Y)-(Piece.X + PieceWidth, Piece.Y + PieceHeight), Pic_PuzzleImage.Backcolor, BF
  419.     For N = TotalPieces To 1 Step -1
  420.         R = SetRectRgn(Region1, Pieces(Priority(N)).X, Pieces(Priority(N)).Y, Pieces(Priority(N)).X + PieceWidth, Pieces(Priority(N)).Y + PieceHeight)
  421.         If CombineRgn(Region3, Region2, Region1, RGN_AND) <> NULLREGION Then
  422.             If MaskNeeded Then
  423.                 Get_Mask_And_Image N
  424.                 R = BitBlt(Pic_PuzzleImage.Hdc, Pieces(Priority(N)).X, Pieces(Priority(N)).Y, PieceWidth, PieceHeight, Pic_PieceMask.Hdc, 0, 0, SRCAND)
  425.                 R = BitBlt(Pic_PuzzleImage.Hdc, Pieces(Priority(N)).X, Pieces(Priority(N)).Y, PieceWidth, PieceHeight, Pic_PieceImage.Hdc, 0, 0, SRCINVERT)
  426.             Else
  427.                 Display_A_Piece (Pic_PuzzleImage.Hdc), N
  428.             End If
  429.         End If
  430.     Next N
  431.     R = SelectClipRgn(Pic_PuzzleImage.Hdc, 0)
  432.  
  433.     If MaskNeeded Then Get_Mask_And_Image 0
  434.  
  435.     X1 = Piece.HomeX + 3 * (PieceWidth \ 8)
  436.     Y1 = Piece.HomeY + 3 * (PieceHeight \ 8)
  437.     X2 = X1 + PieceWidth \ 4
  438.     Y2 = Y1 + PieceHeight \ 4
  439.     R = SetRectRgn(Region4, X1, Y1, X2, Y2)
  440.  
  441.     LastMouseX = X
  442.     LastMouseY = Y
  443.     MovingPiece = TRUE
  444.     
  445. End Sub
  446.  
  447. Sub Menu_Hint_Click ()
  448.  
  449.     For I = 1 To 6
  450.         Pic_Work.Line (Pieces(Priority(0)).X, Pieces(Priority(0)).Y)-(Pieces(Priority(0)).X + PieceWidth, Pieces(Priority(0)).Y + PieceHeight), , BF
  451.         Pic_Work.Line (Pieces(Priority(0)).HomeX, Pieces(Priority(0)).HomeY)-(Pieces(Priority(0)).HomeX + PieceWidth, Pieces(Priority(0)).HomeY + PieceHeight), , BF
  452.     Next
  453.  
  454. End Sub
  455.  
  456. Sub Get_Mask_And_Image (Piece)
  457. Dim MaskROP As Long
  458.  
  459.     If Priority(Piece) < 16 Then MaskROP = NOTSRCCOPY Else MaskROP = SRCCOPY
  460.     R = BitBlt(Pic_PieceMask.Hdc, 0, 0, PieceWidth, PieceHeight, Pic_Mask.Hdc, Pieces(Priority(Piece)).HomeX, Pieces(Priority(Piece)).HomeY, MaskROP)
  461.     R = BitBlt(Pic_PieceImage.Hdc, 0, 0, PieceWidth, PieceHeight, Pic_Bitmap.Hdc, Pieces(Priority(Piece)).HomeX, Pieces(Priority(Piece)).HomeY, SRCCOPY)
  462.     R = BitBlt(Pic_PieceImage.Hdc, 0, 0, PieceWidth, PieceHeight, Pic_PieceMask.Hdc, 0, 0, SRCINVERTANDDEST)
  463.  
  464. End Sub
  465.  
  466. Sub Scrammble_Puzzle ()
  467.             
  468.     Solved = FALSE
  469.     Pic_Work.Cls
  470.     Pic_PuzzleImage.Picture = LoadPicture()
  471.     
  472.     Randomize Timer
  473.     For I = TotalPieces To 0 Step -1
  474.         Pieces(Priority(I)).X = Int(Rnd * (Pic_Work.Width - PieceWidth) + 1)
  475.         Pieces(Priority(I)).Y = Int(Rnd * (Pic_Work.Height - PieceHeight) + 1)
  476.         If MaskNeeded Then
  477.             Get_Mask_And_Image I
  478.             R = BitBlt(Pic_PuzzleImage.Hdc, Pieces(Priority(I)).X, Pieces(Priority(I)).Y, PieceWidth, PieceHeight, Pic_PieceMask.Hdc, 0, 0, SRCAND)
  479.             R = BitBlt(Pic_PuzzleImage.Hdc, Pieces(Priority(I)).X, Pieces(Priority(I)).Y, PieceWidth, PieceHeight, Pic_PieceImage.Hdc, 0, 0, SRCINVERT)
  480.         Else
  481.             Display_A_Piece (Pic_PuzzleImage.Hdc), I
  482.         End If
  483.         If Menu_OptionsSelection(MID_SHOW_SCRAMMBLING).Checked Then R = BitBlt(Pic_Work.Hdc, Pieces(Priority(I)).X, Pieces(Priority(I)).Y, PieceWidth, PieceHeight, Pic_PuzzleImage.Hdc, Pieces(Priority(I)).X, Pieces(Priority(I)).Y, SRCCOPY)
  484.     Next I
  485.     If Not Menu_OptionsSelection(MID_SHOW_SCRAMMBLING).Checked Then Pic_Work.Refresh
  486.  
  487. End Sub
  488.  
  489. Sub Solve_Puzzle ()
  490.     
  491.     Menu_Hint.Enabled = FALSE
  492.     For I = 0 To TotalPieces
  493.         Priority(I) = I
  494.         Pieces(I).X = Pieces(I).HomeX
  495.         Pieces(I).Y = Pieces(I).HomeY
  496.     Next I
  497.     Restore_Bitmap
  498.  
  499. End Sub
  500.  
  501. Sub Animate_Puzzle ()
  502.             
  503.     Menu_Hint.Enabled = FALSE
  504.     Menu_File.Enabled = FALSE
  505.     Menu_Options.Enabled = FALSE
  506.     Menu_Pieces.Enabled = FALSE
  507.     Menu_Hint.Enabled = FALSE
  508.     Menu_Stop.Visible = TRUE
  509.  
  510.     For I = 0 To TotalPieces
  511.         If (Pieces(Priority(0)).X <> Pieces(Priority(0)).HomeX) Or (Pieces(Priority(0)).Y <> Pieces(Priority(0)).HomeY) Then
  512.             XInc = Sgn(Pieces(Priority(0)).X - Pieces(Priority(0)).HomeX) * 14
  513.             YInc = Sgn(Pieces(Priority(0)).Y - Pieces(Priority(0)).HomeY) * 14
  514.             Prepare_To_Move_Piece Pieces(Priority(0)).X, Pieces(Priority(0)).Y
  515.             While (Pieces(Priority(0)).X <> Pieces(Priority(0)).HomeX) Or (Pieces(Priority(0)).Y <> Pieces(Priority(0)).HomeY)
  516.                 If Pieces(Priority(0)).X = Pieces(Priority(0)).HomeX Then XInc = 0
  517.                 If Pieces(Priority(0)).Y = Pieces(Priority(0)).HomeY Then YInc = 0
  518.                 X = Pieces(Priority(0)).X - XInc
  519.                 Y = Pieces(Priority(0)).Y - YInc
  520.                 If Sgn(X - Pieces(Priority(0)).HomeX) <> Sgn(XInc) Then X = Pieces(Priority(0)).HomeX
  521.                 If Sgn(Y - Pieces(Priority(0)).HomeY) <> Sgn(YInc) Then Y = Pieces(Priority(0)).HomeY
  522.                 Move_Piece X, Y
  523.             Wend
  524.             Display_A_Piece (Pic_PuzzleImage.Hdc), 0
  525.         End If
  526.         X = DoEvents()
  527.         If Not Menu_Stop.Visible Then Exit For
  528.         Set_Piece_Priority TotalPieces
  529.     Next I
  530.     MovingPiece = FALSE
  531.     Menu_Stop_Click
  532.  
  533.     Restore_Bitmap
  534.  
  535. End Sub
  536.  
  537. Sub Bring_Pieces_To_Foreground ()
  538.             
  539.     For I = TotalPieces To 0 Step -1
  540.         If (Pieces(Priority(I)).X <> Pieces(Priority(I)).HomeX) Or (Pieces(Priority(I)).Y <> Pieces(Priority(I)).HomeY) Then
  541.             Set_Piece_Priority I
  542.             If MaskNeeded Then Get_Mask_And_Image I
  543.             Display_A_Piece (Pic_PuzzleImage.Hdc), I
  544.         End If
  545.         R = BitBlt(Pic_Work.Hdc, Pieces(Priority(I)).X, Pieces(Priority(I)).Y, PieceWidth, PieceHeight, Pic_PuzzleImage.Hdc, Pieces(Priority(I)).X, Pieces(Priority(I)).Y, SRCCOPY)
  546.     Next I
  547.  
  548. End Sub
  549.  
  550. Sub Pic_Window_Paint ()
  551.  
  552.     If Pic_Work.Visible Then Pic_Window.Line (0, 0)-(Pic_Work.Left + Pic_Work.Width + 2, Pic_Work.Top + Pic_Work.Height + 2), (Not Pic_Window.Backcolor) And &HFFFFFF, B
  553.     
  554. End Sub
  555.  
  556. Sub Outline_Circles_In_Squares ()
  557. Dim Radius As Single
  558.  
  559.     If PieceWidth < PieceHeight Then Radius = PieceWidth / 2 - 5 Else Radius = PieceHeight / 2 - 5
  560.     For Y = 0 To PuzzleSize - 1
  561.         For X = 0 To PuzzleSize - 1
  562.             Pic_Bitmap.Line (X * PieceWidth, Y * PieceHeight)-(X * PieceWidth + PieceWidth - 1, Y * PieceHeight + PieceHeight - 1), , B
  563.             If MaskNeeded <> MID_CIRCELS_IN_SQUARES Then
  564.                 Pic_Bitmap.Circle (X * PieceWidth + PieceWidth / 2, Y * PieceHeight + PieceHeight / 2), Radius
  565.                 Pic_Bitmap.Circle (X * PieceWidth + PieceWidth / 2, Y * PieceHeight + PieceHeight / 2), Radius + 1
  566.             End If
  567.         Next X
  568.     Next Y
  569.  
  570. End Sub
  571.  
  572. Sub Create_Circles_In_Squares_Mask ()
  573. Dim Radius As Single
  574.  
  575.     If PieceWidth < PieceHeight Then Radius = PieceWidth / 2 - 5 Else Radius = PieceHeight / 2 - 5
  576.     For Y = 0 To PuzzleSize - 1
  577.         For X = 0 To PuzzleSize - 1
  578.             Pic_Mask.Circle (X * PieceWidth + PieceWidth / 2, Y * PieceHeight + PieceHeight / 2), Radius
  579.         Next X
  580.     Next Y
  581.  
  582. End Sub
  583.  
  584. Sub Create_Angel_And_Stars_Mask ()
  585.     
  586.     For Y = 1 To 3
  587.         For X = 1 To 3
  588.             If Y = 2 Then Half = 1 Else Half = 2
  589.             Pic_Mask.Circle (X * PieceWidth, Y * PieceHeight), PieceHeight / Half, , , , 2.5
  590.             Pic_Mask.Circle (X * PieceWidth, Y * PieceHeight), PieceWidth / 2, , , , .2
  591.         Next X
  592.     Next Y
  593.  
  594.     For X = 1 To 3
  595.         Pic_Mask.fillstyle = 1
  596.         Pic_Mask.Line (X * PieceWidth - PieceWidth / 2, 2 * PieceHeight - PieceHeight / 2)-(X * PieceWidth + PieceWidth / 2, 2 * PieceHeight + PieceHeight / 2), &HFFFFFF, BF
  597.         Pic_Mask.fillstyle = 0
  598.         Pic_Mask.Circle (X * PieceWidth, 2 * PieceHeight), PieceHeight / 2, , , , 4.5
  599.         Pic_Mask.Circle (X * PieceWidth, 2 * PieceHeight), PieceWidth / 2, , , , .1
  600.     Next X
  601.  
  602. End Sub
  603.  
  604. Sub Create_Elipses_Mask ()
  605.  
  606.     For Y = 1 To 3
  607.         For X = 1 To 3
  608.             If ((X * Y) Mod 2) Or (X * Y) = 4 Then
  609.                 Pic_Mask.Circle (X * PieceWidth, Y * PieceHeight), PieceHeight / 2 - 1, , , , 2.5
  610.             Else
  611.                 Pic_Mask.Circle (X * PieceWidth, Y * PieceHeight), PieceWidth / 2 - 1, , , , .3
  612.             End If
  613.         Next X
  614.     Next Y
  615.  
  616. End Sub
  617.  
  618. Sub Create_Circles_Mask ()
  619. Dim Radius As Single
  620.  
  621.     If PieceWidth < PieceHeight Then Radius = PieceWidth / 2 - 1 Else Radius = PieceHeight / 2 - 1
  622.     For Y = 1 To PuzzleSize - 1
  623.         For X = 1 To PuzzleSize - 1
  624.             Pic_Mask.Circle (X * PieceWidth, Y * PieceHeight), Radius
  625.         Next X
  626.     Next Y
  627.     
  628. End Sub
  629.  
  630. Sub Restore_Bitmap ()
  631.     
  632.     Solved = TRUE
  633.     AutoRedraw = TRUE
  634.     Pic_PuzzleImage.Picture = Image
  635.     AutoRedraw = FALSE
  636.     Pic_Work_Paint
  637.  
  638. End Sub
  639.  
  640. Sub Menu_OutlineSelection_Click (Index As Integer)
  641.     
  642.     Menu_OutlineSelection(Index).Checked = TRUE
  643.     Menu_OutlineSelection(Abs(1 - Index)).Checked = FALSE
  644.  
  645.     Pic_Bitmap.ForeColor = (-Index) And &HFFFFFF
  646.     Prepare_Bitmap FALSE
  647.  
  648. End Sub
  649.  
  650. Sub Menu_BackgroundSelection_Click (Index As Integer)
  651.  
  652.     Menu_BackgroundSelection(Index).Checked = TRUE
  653.     Menu_BackgroundSelection(Abs(1 - Index)).Checked = FALSE
  654.  
  655.     Pic_Work.Backcolor = Pic_Window.Backcolor
  656.     Pic_PuzzleImage.Backcolor = Pic_Window.Backcolor
  657.     Pic_Window.Backcolor = (Not Pic_Work.Backcolor) And &HFFFFFF
  658.     
  659.     Prepare_Bitmap FALSE
  660.     Pic_Window.Refresh
  661.  
  662. End Sub
  663.  
  664. Sub Menu_File_Click ()
  665.  
  666.     Menu_FileSelection(MID_CLIPBOARD).Enabled = ClipBoard.GetFormat(2)
  667.  
  668. End Sub
  669.  
  670. Sub Menu_HelpSelection_Click (Index As Integer)
  671.  
  672.     AboutBox.Show MODAL
  673.  
  674. End Sub
  675.  
  676.