00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032
00033
00034
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #include "stratagus.h"
00041 #include "video.h"
00042 #include "unittype.h"
00043 #include "player.h"
00044 #include "unit.h"
00045 #include "cursor.h"
00046 #include "map.h"
00047 #include "interface.h"
00048 #include "ui.h"
00049 #include "editor.h"
00050
00051 #include "intern_video.h"
00052
00053
00054
00055
00056
00062 std::vector<CCursor> AllCursors;
00063
00064 CursorStates CursorState;
00065 int CursorAction;
00066 int CursorValue;
00067
00068
00069 int CursorX;
00070 int CursorY;
00071
00072 int CursorStartX;
00073 int CursorStartY;
00074
00075 int SubScrollX;
00076 int SubScrollY;
00077
00079 int CursorStartScrMapX;
00081 int CursorStartScrMapY;
00082
00083
00084
00085 CUnitType *CursorBuilding;
00086
00087
00088
00089 CCursor *GameCursor;
00090
00091 static SDL_Surface *HiddenSurface;
00092
00093
00094
00095
00096
00100 void LoadCursors()
00101 {
00102 std::vector<CCursor>::iterator i;
00103
00104 for (i = AllCursors.begin(); i != AllCursors.end(); ++i) {
00105 if ((*i).G && !(*i).G->IsLoaded()) {
00106 ShowLoadProgress("Cursor %s", (*i).G->File.c_str());
00107 (*i).G->Load();
00108 (*i).G->UseDisplayFormat();
00109 }
00110 }
00111 }
00112
00122 CCursor *CursorByIdent(const std::string &ident)
00123 {
00124 std::vector<CCursor>::iterator i;
00125
00126 for (i = AllCursors.begin(); i != AllCursors.end(); ++i) {
00127 if ((*i).Ident != ident) {
00128 continue;
00129 }
00130 return &(*i);
00131 }
00132 DebugPrint("Cursor `%s' not found, please check your code.\n" _C_ ident.c_str());
00133 return NULL;
00134 }
00135
00144 static void DrawVisibleRectangleCursor(int x, int y, int x1, int y1)
00145 {
00146 int w;
00147 int h;
00148 const CViewport *vp;
00149
00150
00151
00152
00153
00154 vp = UI.SelectedViewport;
00155 if (x1 < vp->X) {
00156 x1 = vp->X;
00157 } else if (x1 > vp->EndX) {
00158 x1 = vp->EndX;
00159 }
00160 if (y1 < vp->Y) {
00161 y1 = vp->Y;
00162 } else if (y1 > vp->EndY) {
00163 y1 = vp->EndY;
00164 }
00165
00166 if (x > x1) {
00167 w = x - x1 + 1;
00168 x = x1;
00169 } else {
00170 w = x1 - x + 1;
00171 }
00172 if (y > y1) {
00173 h = y - y1 + 1;
00174 y = y1;
00175 } else {
00176 h = y1 - y + 1;
00177 }
00178
00179 if (w && h) {
00180 Video.DrawRectangleClip(ColorGreen, x, y, w, h);
00181 }
00182 }
00183
00187 static void DrawBuildingCursor(void)
00188 {
00189 int i;
00190 int x;
00191 int y;
00192 int mx;
00193 int my;
00194 Uint32 color;
00195 int f;
00196 int w;
00197 int w0;
00198 int h;
00199 int mask;
00200 const CViewport *vp;
00201 CUnit *ontop;
00202
00203
00204 vp = UI.MouseViewport;
00205 x = CursorX - (CursorX - vp->X + vp->OffsetX) % TileSizeX;
00206 y = CursorY - (CursorY - vp->Y + vp->OffsetY) % TileSizeY;
00207 mx = vp->Viewport2MapX(x);
00208 my = vp->Viewport2MapY(y);
00209 ontop = NULL;
00210
00211
00212
00213
00214 PushClipping();
00215 SetClipping(vp->X, vp->Y, vp->EndX, vp->EndY);
00216 DrawShadow(NULL, CursorBuilding, CursorBuilding->StillFrame, x, y);
00217 DrawUnitType(CursorBuilding, CursorBuilding->Sprite, ThisPlayer->Index,
00218 CursorBuilding->StillFrame, x, y);
00219
00220
00221
00222
00223 if (NumSelected) {
00224 f = 1;
00225 for (i = 0; f && i < NumSelected; ++i) {
00226 f = ((ontop = CanBuildHere(Selected[i], CursorBuilding, mx, my)) != NULL);
00227
00228 ontop = (ontop == Selected[i] ? NULL : ontop);
00229 }
00230 } else {
00231 f = ((ontop = CanBuildHere(NoUnitP, CursorBuilding, mx, my)) != NULL);
00232 if (!Editor.Running || (Editor.Running && ontop == (CUnit *)1)) {
00233 ontop = NULL;
00234 }
00235 }
00236
00237 mask = CursorBuilding->MovementMask;
00238 h = CursorBuilding->TileHeight;
00239
00240 if (my + h > vp->MapY + vp->MapHeight) {
00241 h = vp->MapY + vp->MapHeight - my;
00242 }
00243 w0 = CursorBuilding->TileWidth;
00244 if (mx + w0 > vp->MapX + vp->MapWidth) {
00245 w0 = vp->MapX + vp->MapWidth - mx;
00246 }
00247 while (h--) {
00248 w = w0;
00249 while (w--) {
00250 if (f && (ontop ||
00251 CanBuildOn(mx + w, my + h, MapFogFilterFlags(ThisPlayer, mx + w, my + h,
00252 mask & ((NumSelected &&
00253 Selected[0]->X == mx + w && Selected[0]->Y == my + h) ?
00254 ~(MapFieldLandUnit | MapFieldSeaUnit) : -1)))) &&
00255 Map.IsFieldExplored(ThisPlayer, mx + w, my + h)) {
00256 color = ColorGreen;
00257 } else {
00258 color = ColorRed;
00259 }
00260 Video.FillTransRectangleClip(color, x + w * TileSizeX, y + h *
00261 TileSizeY, TileSizeX, TileSizeY, 95);
00262 }
00263 }
00264 PopClipping();
00265 }
00266
00267
00271 void DrawCursor(void)
00272 {
00273
00274 if (CursorState == CursorStateRectangle &&
00275 (CursorStartX != CursorX || CursorStartY != CursorY)) {
00276 DrawVisibleRectangleCursor(
00277 CursorStartScrMapX + UI.MouseViewport->X - TileSizeX * UI.MouseViewport->MapX - UI.MouseViewport->OffsetX,
00278 CursorStartScrMapY + UI.MouseViewport->Y - TileSizeY * UI.MouseViewport->MapY - UI.MouseViewport->OffsetY,
00279 CursorX, CursorY);
00280 } else if (CursorBuilding && CursorOn == CursorOnMap) {
00281
00282 DrawBuildingCursor();
00283 }
00284
00285 if (!UseOpenGL && !GameRunning && !Editor.Running && !PatchEditorRunning && GameCursor) {
00286 if (!HiddenSurface ||
00287 HiddenSurface->w != GameCursor->G->getWidth() ||
00288 HiddenSurface->h != GameCursor->G->getHeight())
00289 {
00290 if (HiddenSurface) {
00291 SDL_FreeSurface(HiddenSurface);
00292 }
00293
00294 HiddenSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
00295 GameCursor->G->getWidth(),
00296 GameCursor->G->getHeight(),
00297 TheScreen->format->BitsPerPixel,
00298 TheScreen->format->Rmask,
00299 TheScreen->format->Gmask,
00300 TheScreen->format->Bmask,
00301 TheScreen->format->Amask);
00302 }
00303
00304 SDL_Rect srcRect = {
00305 CursorX - GameCursor->HotX,
00306 CursorY - GameCursor->HotY,
00307 GameCursor->G->getWidth(),
00308 GameCursor->G->getHeight()
00309 };
00310 SDL_BlitSurface(TheScreen, &srcRect, HiddenSurface, NULL);
00311 }
00312
00313
00314
00315
00316
00317
00318 if (GameCursor) {
00319 GameCursor->G->DrawFrameClip(GameCursor->SpriteFrame,
00320 CursorX - GameCursor->HotX, CursorY - GameCursor->HotY);
00321 }
00322 }
00323
00327 void HideCursor(void)
00328 {
00329 if (!UseOpenGL && !GameRunning && !Editor.Running && !PatchEditorRunning && GameCursor) {
00330 SDL_Rect dstRect = {
00331 CursorX - GameCursor->HotX,
00332 CursorY - GameCursor->HotY,
00333 0,
00334 0
00335 };
00336 SDL_BlitSurface(HiddenSurface, NULL, TheScreen, &dstRect);
00337 }
00338 }
00339
00345 void CursorAnimate(unsigned ticks)
00346 {
00347 static unsigned last = 0;
00348
00349 if (!GameCursor || !GameCursor->FrameRate) {
00350 return;
00351 }
00352 if (ticks > last + GameCursor->FrameRate) {
00353 last = ticks + GameCursor->FrameRate;
00354 GameCursor->SpriteFrame++;
00355 if ((GameCursor->SpriteFrame & 127) >= GameCursor->G->NumFrames) {
00356 GameCursor->SpriteFrame = 0;
00357 }
00358 }
00359 }
00360
00364 void InitVideoCursors(void)
00365 {
00366 }
00367
00371 void CleanCursors(void)
00372 {
00373 std::vector<CCursor>::iterator i;
00374
00375 for (i = AllCursors.begin(); i != AllCursors.end(); ++i) {
00376 CGraphic::Free((*i).G);
00377 }
00378 AllCursors.clear();
00379
00380 CursorBuilding = NULL;
00381 GameCursor = NULL;
00382 UnitUnderCursor = NoUnitP;
00383 }
00384