rnd-20090623-1-src
[rocksndiamonds.git] / src / game_sp / Marker.c
1 // ----------------------------------------------------------------------------
2 // Marker.c
3 // ----------------------------------------------------------------------------
4
5 #include "Marker.h"
6
7 static boolean IsPort(long i);
8 static void LimitXY(int *X, int *Y);
9 static void SortData();
10
11 // --- VERSION 1.0 CLASS
12 // --- BEGIN
13 // ---   MultiUse = -1  'True  // True
14 // ---   Persistable = 0  'NotPersistable  // NotPersistable
15 // ---   DataBindingBehavior = 0  'vbNone  // vbNone
16 // ---   DataSourceBehavior  = 0  'vbNone  // vbNone
17 // ---   MTSTransactionMode  = 0  'NotAnMTSObject  // NotAnMTSObject
18 // --- END
19
20 static char *VB_Name = "MarkerObject";
21 static boolean VB_GlobalNameSpace = False;
22 static boolean VB_Creatable = True;
23 static boolean VB_PredeclaredId = False;
24 static boolean VB_Exposed = False;
25 // --- Option Explicit
26
27 long mIndex1, mIndex2;
28 int X1, X2, Y1, Y2;
29 int XMin, YMin;
30 boolean mVisible;
31
32 byte *SelectionData;
33
34 int Marker_Get_Width()
35 {
36   int Width;
37
38   Width = Abs(X2 - X1) + 1;
39
40   return Width;
41 }
42
43 int Marker_Get_Height()
44 {
45   int Height;
46
47   Height = Abs(Y2 - Y1) + 1;
48
49   return Height;
50 }
51
52 int Marker_Get_Left()
53 {
54   int Left;
55
56   SortData();
57   Left = XMin;
58
59   return Left;
60 }
61
62 int Marker_Get_Top()
63 {
64   int Top;
65
66   SortData();
67   Top = YMin;
68
69   return Top;
70 }
71
72 static void LimitXY(int *X, int *Y)
73 {
74   if (*X < DisplayMinX)
75     *X = DisplayMinX;
76
77   if (DisplayMaxX < *X)
78     *X = DisplayMaxX;
79
80   if (*Y < DisplayMinY)
81     *Y = DisplayMinY;
82
83   if (DisplayMaxY < *Y)
84     *Y = DisplayMaxY;
85 }
86
87 void Marker_SetPoint1(int X, int Y)
88 {
89   LimitXY(&X, &Y);
90   X1 = X;
91   Y1 = Y;
92   X2 = X;
93   Y2 = Y;
94 }
95
96 void Marker_SetPoint2(int X, int Y)
97 {
98   char *T;
99
100   LimitXY(&X, &Y);
101   X2 = X;
102   Y2 = Y;
103   T = CAT("(", Marker_Get_Width(), " x ", Marker_Get_Height(), ")");
104   MainForm.lblFrameCount = T;
105 }
106
107 static void SortData()
108 {
109   int Tmp;
110
111   XMin = (X2 < X1 ?  X2 :  X2);
112   YMin = (Y2 < Y1 ?  Y2 :  Y2);
113 }
114
115 void Marker_ShowMarker(boolean ShowFlag)
116 {
117   mVisible = ShowFlag;
118   Marker_MoveMarker();
119 }
120
121 void Marker_RefreshMarker()
122 {
123   int L, T, R, B;
124   long Tmp;
125
126   if (! mVisible)
127     return;
128
129   LimitXY(&X1, &Y1);
130   LimitXY(&X2, &Y2);
131   SortData();
132   L = DigitXPos(XMin) - 1;
133   T = DigitYPos(YMin) - 1;
134   R = L + StretchWidth * Marker_Get_Width() + 1;
135   B = T + StretchWidth * Marker_Get_Height() + 1;
136   MainForm.picPane.Line(L, T, R, B, 0xFFFFFF, B);
137 }
138
139 void Marker_MoveMarker()
140 {
141   int L, T, R, B;
142   long Tmp;
143
144   if (! mVisible)
145     return;
146
147   LimitXY(&X1, &Y1);
148   LimitXY(&X2, &Y2);
149   SortData();
150   Stage.Blt();
151   Tmp = GetSI(XMin, YMin);
152   if (Marker_Get_Width() == 1 && Marker_Get_Height() == 1 && IsPort(Tmp))
153   {
154     SpLoadMenu();
155     MainForm.menSP.Enabled = True;
156   }
157   else
158   {
159     MainForm.menSP.Enabled = False;
160   }
161 }
162
163 static boolean IsPort(long i)
164 {
165   static boolean IsPort;
166
167   int ax;
168
169   IsPort = False;
170   ax = DisPlayField[i];
171   if (fiOrangeDisk < ax && ax < fiSnikSnak)
172     IsPort = True;
173
174   return IsPort;
175 }
176
177 void Marker_Copy()
178 {
179   int X, Y, MaxX, MaxY;
180   long Tmp;
181   char *TPath;
182   int FNum;
183
184   SortData();
185   MaxX = Marker_Get_Width() - 1;
186   MaxY = Marker_Get_Height() - 1;
187   SelectionData = REDIM_2D(sizeof(byte), 0, MaxX + 1 - 1, 0, MaxY + 1 - 1);
188   for (Y = 0; Y <= MaxY; Y++)
189   {
190     for (X = 0; X <= MaxX; X++)
191     {
192       Tmp = FieldWidth * (YMin + Y) + XMin + X;
193
194       // --- On Error GoTo CopyEH
195       SelectionData[X, Y] = DisPlayField[Tmp];
196       // --- On Error GoTo 0
197
198     }
199   }
200
201   TPath = CAT(App.Path, "/Mpx.clp");
202   if (FileExists(TPath))
203     MayKill(TPath);
204
205   FNum = FreeFile();
206
207   // --- On Error GoTo CopyEH
208   FNum = fopen(TPath, "wb");
209   FILE_PUT(FNum, -1, &MaxX, sizeof(MaxX));
210   FILE_PUT(FNum, -1, &MaxY, sizeof(MaxY));
211   FILE_PUT(FNum, -1, &SelectionData, sizeof(SelectionData));
212   fclose(FNum);
213   SelectionData = REDIM_1D(sizeof(byte), 0, 1 - 1);
214   return;
215
216 CopyEH:
217   Beep();
218 }
219
220 void Marker_Paste()
221 {
222   int X, Y, MaxX, MaxY;
223   long Tmp;
224   char *TPath;
225   int FNum;
226
227   TPath = CAT(App.Path, "/Mpx.clp");
228   if (! FileExists(TPath))
229   {
230     Beep();
231     return;
232   }
233
234   FNum = FreeFile();
235
236   // --- On Error GoTo PasteEH
237   FNum = fopen(TPath, "rb");
238   FILE_GET(FNum, -1, &MaxX, sizeof(MaxX));
239   FILE_GET(FNum, -1, &MaxY, sizeof(MaxY));
240   SelectionData = REDIM_2D(sizeof(byte), 0, MaxX + 1 - 1, 0, MaxY + 1 - 1);
241   FILE_GET(FNum, -1, &SelectionData, sizeof(SelectionData));
242   fclose(FNum);
243   // --- On Error GoTo 0
244
245   SortData();
246   if (Marker_Get_Width() <= MaxX)
247     MaxX = Marker_Get_Width() - 1;
248
249   if (Marker_Get_Height() <= MaxY)
250     MaxY = Marker_Get_Height() - 1;
251
252   for (Y = 0; Y <= MaxY; Y++)
253   {
254     for (X = 0; X <= MaxX; X++)
255     {
256       Tmp = FieldWidth * (YMin + Y) + XMin + X;
257
258       // --- On Error GoTo PasteEH
259       DisPlayField[Tmp] = SelectionData[X, Y];
260       PlayField16[Tmp] = UnEdSprite(SelectionData[X, Y]);
261       // --- On Error GoTo 0
262
263     }
264   }
265
266   Let_ModifiedFlag(True);
267 PasteEH:
268   Beep();
269 }
270
271 static void Class_Initialize()
272 {
273   mVisible = False;
274 }