3 static char * names[Player][PieceType] =
5 { "", "WhitePawn", "WhiteKnigh", "WhiteBisho", "WhiteRook", "WhiteQueen", "WhiteKing" },
6 { "", "BlackPawn", "BlackKnigh", "BlackBisho", "BlackRook", "BlackQueen", "BlackKing" },
9 define SQUARE = squareSize; // 160;
10 define SQUARE_OFFSET = SQUARE * 3.5f;
12 class Chess3D : Window
16 attached, fov = 45, zMin = 50,zMax = 5000,
17 position = { 0, 0, -1000 },
18 orientation = Euler { 30, 30, 0 }
24 bool moving, lightMoving;
26 Euler startOrientation;
28 FillModeValue fillMode;
29 ChessState * chessState;
46 Menu viewMenu { menu, "View", v };
47 MenuItem itemAntiAlias
49 viewMenu, "Anti Aliased", s, checkable = true, checked = antiAlias;
50 bool NotifySelect(MenuItem selection, Modifiers mods)
58 isActiveClient = true, background = black, borderStyle = sizable, hasMaximize = true, hasMinimize = true;
60 void RenderPiece(Piece atBoard, int x, int y, bool high)
62 Player player = atBoard.player;
63 PieceType type = atBoard.type;
67 char * name = names[player][type];
68 Object object = chessSet.Find(name);
75 Piece overAtBoard = chessState->board[y][x];
76 Player overPlayer = overAtBoard.player;
77 PieceType overType = overAtBoard.type;
80 char * name = names[overPlayer][overType];
81 Object over = chessSet.Find(name);
83 height = over.max.y - over.min.y;
87 object.flags.root = true;
89 object.transform.position = {
90 x * SQUARE - SQUARE_OFFSET,
92 y * SQUARE - SQUARE_OFFSET };
94 object.UpdateTransform();
96 object.tag = (void *)(((y)*8)+(x)+1);
97 display.DrawObject(object);
102 void RenderSquare(int x, int y)
104 if(x >= 0 && x < 8 && y >= 0 && y < 8)
106 Piece atBoard = chessState->board[y][x];
108 if(useDrag && pieceSelected)
110 if(x == start.x && y == start.y) return;
111 if(x == dragging.x && y == dragging.y)
113 Piece atBoardStart = chessState->board[start.y][start.x];
114 if(atBoard && atBoard.player != atBoardStart.player) return;
117 RenderPiece(atBoard, x, y, false);
123 display.DrawObject(chessBoard);
125 if(chessState->gameRunning)
132 if(useDrag && pieceSelected)
134 Piece atBoard = chessState->board[start.y][start.x];
135 Piece atBoardDrag = chessState->board[dragging.y][dragging.x];
136 RenderPiece(atBoard, dragging.x, dragging.y,
137 (dragging.x != start.x || dragging.y != start.y) &&
138 atBoardDrag && atBoardDrag.player == atBoard.player);
143 void OnUnloadGraphics()
145 displaySystem.ClearMaterials();
146 displaySystem.ClearTextures();
147 displaySystem.ClearMeshes();
150 void OnPosition(int x, int y, int w, int h)
152 camera.Setup(w, h, null);
155 bool OnLeftButtonDown(int x, int y, Modifiers mods)
159 display.StartSelection(x,y, 0,0);
160 display.SetCamera(null, camera);
161 display.CollectHits();
164 if(chessState->gameRunning)
167 for(cy = 0; cy < 8; cy++)
168 for(cx = 0; cx < 8; cx++)
169 RenderSquare(cx, cy);
172 if(display.GetHits(list))
174 HitRecord hit = list.first;
175 int tag = ((int)hit.tags[0]) - 1;
176 int sx = tag & 7, sy = tag >> 3;
180 pieceSelected = false;
181 ((Chess)master).ProcessUserMove(start.x, start.y, sx, sy);
183 else if(chessState->board[sy][sx] &&
184 chessState->isLocalPlayer[chessState->turn] &&
185 chessState->board[sy][sx].player == chessState->turn)
189 Vector3D viewSpace, worldSpace;
190 display.IntersectPolygons();
191 RenderSquare(sx, sy);
192 display.GetIntersect(viewSpace);
194 camera.Untransform(viewSpace, worldSpace);
196 dragY = worldSpace.y;
201 pieceSelected = true;
206 OnMouseMove(x, y, mods);
211 else if(display.DrawObject(chessBoard) && !moving && !lightMoving)
215 startOrientation = camera.orientation;
219 display.SetCamera(null, null);
220 display.StopSelection();
226 bool OnLeftButtonUp(int x, int y, Modifiers mods)
233 if(useDrag && pieceSelected)
236 ((Chess)master).ProcessUserMove(start.x, start.y, dragging.x, dragging.y);
238 pieceSelected = false;
243 bool OnRightButtonDown(int x, int y, Modifiers mods)
245 if(!moving && !lightMoving)
249 startOrientation = light.orientation;
256 bool OnRightButtonUp(int x, int y, Modifiers mods)
266 bool OnMouseMove(int x, int y, Modifiers mods)
272 startOrientation.yaw - (x - startPosition.x),
273 startOrientation.pitch + (y - startPosition.y),
276 if(angle.pitch > 90) angle.pitch = 90;
277 if(angle.pitch < 2) angle.pitch = 2;
278 camera.orientation = angle;
284 light.orientation = Euler
286 startOrientation.yaw + (x - startPosition.x),
287 startOrientation.pitch + (y - startPosition.y),
293 else if(pieceSelected && useDrag)
295 Vector3D p, v1, v2, w1, w2, vector;
300 // Compute ray of pixel
307 camera.Unproject(p, v2);
309 // Convert ray to world space
310 camera.Untransform(v1, w1);
311 camera.Untransform(v2, w2);
313 line.delta.x = w2.x - w1.x;
314 line.delta.y = w2.y - w1.y;
315 line.delta.z = w2.z - w1.z;
317 // Compute plane of selection in world space
318 vector = { 0,dragY,0 };
321 plane.FromPoints(vector, w1, w2);
324 plane.IntersectLine(line, vector);
326 sx = (int)((vector.x + SQUARE * 4) / SQUARE);
327 sy = (int)((vector.z + SQUARE * 4) / SQUARE);
328 sx = Max(Min(sx, 7), 0);
329 sy = Max(Min(sy, 7), 0);
338 bool OnKeyHit(Key key, unichar ch)
340 switch((SmartKey)key)
344 camera.position.z *= 1.1f;
345 if(camera.position.z <= -3800)
346 camera.position.z = -3800;
350 case equal: camera.position.z /= 1.1f;
351 if(camera.position.z >= -1100)
352 camera.position.z = -1100;
359 bool OnLoadGraphics()
361 display.vSync = true;
362 chessSet.Load(":chessSet.3ds", null, displaySystem);
364 //chessSet.transform.orientation.RotateY(45);
365 //chessSet.UpdateTransform();
367 chessBoard = chessSet.Find("Rectangle0");
368 chessBoard.flags.root = true;
371 Object queen = chessSet.Find(names[White][Queen]);
372 Object king = chessSet.Find(names[White][King]);
374 squareSize = king.transform.position.x - queen.transform.position.x;
375 offsetY = king.transform.position.y;
379 camera.position.z = - chessBoard.radius * 2.5f;
381 camera.target = chessBoard;
386 void OnRedraw(Surface surface)
388 //surface.SetBackground(white);
389 surface.Clear(colorAndDepth);
392 display.antiAlias = antiAlias;
393 display.SetCamera(surface, camera);
394 //display.fogDensity = 0.0002f;
395 display.antiAlias = antiAlias;
397 display.SetLight(0, light);
398 display.fillMode = fillMode;
402 display.SetCamera(surface, null);
404 display.fillMode = solid;
410 //fillMode = wireframe;
412 light.diffuse = white;
413 light.specular = white;
415 light.orientation = Euler { pitch = 90 };
420 property ChessState * chessState { set { chessState = value; } }