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 "font.h"
00043 #include "interface.h"
00044 #include "map.h"
00045 #include "ui.h"
00046 #include "menus.h"
00047 #include "iolib.h"
00048 #include "unit.h"
00049 #include "title.h"
00050
00051
00052
00053
00054
00055 bool RightButtonAttacks;
00056
00057
00061 CUserInterface UI;
00062
00063
00064
00065
00066
00067 CUserInterface::CUserInterface() :
00068 MouseScroll(false), KeyScroll(false),
00069 MouseScrollSpeedDefault(0), MouseScrollSpeedControl(0),
00070 MouseWarpX(0), MouseWarpY(0),
00071 SingleSelectedButton(NULL),
00072 MaxSelectedFont(NULL), MaxSelectedTextX(0), MaxSelectedTextY(0),
00073 SingleTrainingButton(NULL),
00074 SingleTrainingFont(NULL), SingleTrainingTextX(0), SingleTrainingTextY(0),
00075 TrainingFont(NULL), TrainingTextX(0), TrainingTextY(0),
00076 CompletedBarColor(0), CompletedBarShadow(0),
00077 ViewportMode(VIEWPORT_SINGLE), MouseViewport(NULL),
00078 SelectedViewport(NULL), NumViewports(0),
00079 MessageFont(NULL), MessageScrollSpeed(5),
00080 ViewportCursorColor(0), Offset640X(0), Offset480Y(0),
00081 VictoryBackgroundG(NULL), DefeatBackgroundG(NULL)
00082 {
00083 memset(&CompletedBarColorRGB, 0, sizeof(CompletedBarColorRGB));
00084
00085 Point.Name = "cursor-point";
00086 Glass.Name = "cursor-glass";
00087 Cross.Name = "cursor-cross";
00088 YellowHair.Name = "cursor-yellow-hair";
00089 GreenHair.Name = "cursor-green-hair";
00090 RedHair.Name = "cursor-red-hair";
00091 Scroll.Name = "cursor-scroll";
00092
00093 ArrowE.Name = "cursor-arrow-e";
00094 ArrowNE.Name = "cursor-arrow-ne";
00095 ArrowN.Name = "cursor-arrow-n";
00096 ArrowNW.Name = "cursor-arrow-nw";
00097 ArrowW.Name = "cursor-arrow-w";
00098 ArrowSW.Name = "cursor-arrow-sw";
00099 ArrowS.Name = "cursor-arrow-s";
00100 ArrowSE.Name = "cursor-arrow-se";
00101
00102 NormalFontColor = "light-blue";
00103 ReverseFontColor = "yellow";
00104 }
00105
00106
00110 void InitUserInterface(void)
00111 {
00112 UI.Offset640X = (Video.Width - 640) / 2;
00113 UI.Offset480Y = (Video.Height - 480) / 2;
00114
00115
00116
00117
00118 if (Map.Info.MapWidth) {
00119 if (UI.MapArea.EndX > Map.Info.MapWidth * TileSizeX - 1) {
00120 UI.MapArea.EndX = Map.Info.MapWidth * TileSizeX - 1;
00121 }
00122 if (UI.MapArea.EndY > Map.Info.MapHeight * TileSizeY - 1) {
00123 UI.MapArea.EndY = Map.Info.MapHeight * TileSizeY - 1;
00124 }
00125 }
00126
00127 UI.SelectedViewport = UI.Viewports;
00128
00129 SetViewportMode(VIEWPORT_SINGLE);
00130
00131 UI.CompletedBarColor = Video.MapRGB(TheScreen->format,
00132 UI.CompletedBarColorRGB.r,
00133 UI.CompletedBarColorRGB.g,
00134 UI.CompletedBarColorRGB.b);
00135 UI.ViewportCursorColor = ColorWhite;
00136 }
00137
00141 void CursorConfig::Load()
00142 {
00143 Assert(!Name.empty());
00144 Cursor = CursorByIdent(Name);
00145 Assert(Name == Cursor->Ident);
00146 }
00147
00151 void CUserInterface::Load(void)
00152 {
00153 int i;
00154
00155
00156
00157
00158 for (i = 0; i < (int)Fillers.size(); ++i) {
00159 Fillers[i].G->Load();
00160 Fillers[i].G->UseDisplayFormat();
00161 }
00162
00163 for (i = 0; i < MaxCosts; ++i) {
00164 if (Resources[i].G) {
00165 Resources[i].G->Load();
00166 Resources[i].G->UseDisplayFormat();
00167 }
00168 }
00169
00170 if (ButtonPanel.G) {
00171 ButtonPanel.G->Load();
00172 ButtonPanel.G->UseDisplayFormat();
00173 }
00174 if (PieMenu.G) {
00175 PieMenu.G->Load();
00176 PieMenu.G->UseDisplayFormat();
00177 }
00178
00179
00180
00181
00182 Point.Load();
00183 Glass.Load();
00184 Cross.Load();
00185 YellowHair.Load();
00186 GreenHair.Load();
00187 RedHair.Load();
00188 Scroll.Load();
00189
00190 ArrowE.Load();
00191 ArrowNE.Load();
00192 ArrowN.Load();
00193 ArrowNW.Load();
00194 ArrowW.Load();
00195 ArrowSW.Load();
00196 ArrowS.Load();
00197 ArrowSE.Load();
00198 }
00199
00206 static void SaveViewports(CFile *file, const CUserInterface *ui)
00207 {
00208 int i;
00209 const CViewport *vp;
00210
00211 file->printf("DefineViewports(\"mode\", %d", ui->ViewportMode);
00212 for (i = 0; i < ui->NumViewports; ++i) {
00213 vp = &ui->Viewports[i];
00214 file->printf(",\n \"viewport\", {%d, %d, %d}", vp->MapX, vp->MapY,
00215 vp->Unit ? UnitNumber(vp->Unit) : -1);
00216 }
00217 file->printf(")\n\n");
00218 }
00219
00225 void SaveUserInterface(CFile *file)
00226 {
00227 SaveViewports(file, &UI);
00228 }
00229
00233 CUserInterface::~CUserInterface()
00234 {
00235 }
00236
00240 void CleanUserInterface(void)
00241 {
00242 int i;
00243
00244
00245 for (i = 0; i < (int)UI.Fillers.size(); ++i) {
00246 CGraphic::Free(UI.Fillers[i].G);
00247 }
00248 UI.Fillers.clear();
00249
00250
00251 for (i = 0; i < MaxCosts; ++i) {
00252 CGraphic::Free(UI.Resources[i].G);
00253 }
00254
00255 delete UI.SingleSelectedButton;
00256 UI.SelectedButtons.clear();
00257 delete UI.SingleTrainingButton;
00258 UI.SingleTrainingText.clear();
00259 UI.TrainingButtons.clear();
00260 UI.TrainingText.clear();
00261 UI.TransportingButtons.clear();
00262
00263
00264 CGraphic::Free(UI.ButtonPanel.G);
00265
00266
00267 CGraphic::Free(UI.PieMenu.G);
00268
00269
00270 CGraphic::Free(UI.VictoryBackgroundG);
00271 CGraphic::Free(UI.DefeatBackgroundG);
00272
00273
00274 if (TitleScreens) {
00275 for (i = 0; TitleScreens[i]; ++i) {
00276 delete TitleScreens[i];
00277 }
00278 delete[] TitleScreens;
00279 TitleScreens = NULL;
00280 }
00281 }
00282
00283 #ifdef DEBUG
00284 void FreeButtonStyles()
00285 {
00286 std::map<std::string, ButtonStyle *>::iterator i;
00287 for (i = ButtonStyleHash.begin(); i != ButtonStyleHash.end(); ++i) {
00288 delete (*i).second;
00289 }
00290 ButtonStyleHash.clear();
00291 }
00292 #endif
00293
00307 CViewport *GetViewport(int x, int y)
00308 {
00309 CViewport *vp;
00310
00311 for (vp = UI.Viewports; vp < UI.Viewports + UI.NumViewports; ++vp) {
00312 if (x >= vp->X && x <= vp->EndX && y >= vp->Y && y <= vp->EndY) {
00313 return vp;
00314 }
00315 }
00316 return NULL;
00317 }
00318
00330 static void FinishViewportModeConfiguration(CViewport new_vps[], int num_vps)
00331 {
00332 int i;
00333
00334 if (UI.NumViewports < num_vps) {
00335
00336 for (i = 0; i < num_vps; ++i) {
00337 const CViewport *vp;
00338
00339 new_vps[i].MapX = 0;
00340 new_vps[i].MapY = 0;
00341 vp = GetViewport(new_vps[i].X, new_vps[i].Y);
00342 if (vp) {
00343 new_vps[i].OffsetX = new_vps[i].X - vp->X + vp->MapX * TileSizeX + vp->OffsetX;
00344 new_vps[i].OffsetY = new_vps[i].Y - vp->Y + vp->MapY * TileSizeY + vp->OffsetY;
00345 } else {
00346 new_vps[i].OffsetX = 0;
00347 new_vps[i].OffsetY = 0;
00348 }
00349 }
00350 } else {
00351 for (i = 0; i < num_vps; ++i) {
00352 new_vps[i].MapX = UI.Viewports[i].MapX;
00353 new_vps[i].MapY = UI.Viewports[i].MapY;
00354 new_vps[i].OffsetX = UI.Viewports[i].OffsetX;
00355 new_vps[i].OffsetY = UI.Viewports[i].OffsetY;
00356 }
00357 }
00358
00359
00360 for (i = 0; i < num_vps; ++i) {
00361 CViewport *vp;
00362
00363 vp = UI.Viewports + i;
00364 vp->X = new_vps[i].X;
00365 vp->EndX = new_vps[i].EndX;
00366 vp->Y = new_vps[i].Y;
00367 vp->EndY = new_vps[i].EndY;
00368 vp->Set(new_vps[i].MapX, new_vps[i].MapY, new_vps[i].OffsetX, new_vps[i].OffsetY);
00369 }
00370 UI.NumViewports = num_vps;
00371
00372
00373
00374
00375 UI.MouseViewport = GetViewport(CursorX, CursorY);
00376 if (UI.SelectedViewport > UI.Viewports + UI.NumViewports - 1) {
00377 UI.SelectedViewport = UI.Viewports + UI.NumViewports - 1;
00378 }
00379 }
00380
00397 static void ClipViewport(CViewport *vp, int ClipX, int ClipY)
00398 {
00399
00400 vp->EndX = vp->X + Map.Info.MapWidth * TileSizeX - 1;
00401 vp->EndY = vp->Y + Map.Info.MapHeight * TileSizeY - 1;
00402
00403
00404 if (vp->EndX > ClipX) {
00405 vp->EndX = ClipX;
00406 }
00407
00408
00409 if (vp->EndY > ClipY) {
00410 vp->EndY = ClipY;
00411 }
00412
00413 Assert(vp->EndX <= UI.MapArea.EndX);
00414 Assert(vp->EndY <= UI.MapArea.EndY);
00415 }
00416
00425 static void SetViewportModeSingle(void)
00426 {
00427 CViewport new_vps[MAX_NUM_VIEWPORTS];
00428
00429 DebugPrint("Single viewport set\n");
00430
00431 new_vps[0].X = UI.MapArea.X;
00432 new_vps[0].Y = UI.MapArea.Y;
00433 ClipViewport(new_vps, UI.MapArea.EndX, UI.MapArea.EndY);
00434
00435 FinishViewportModeConfiguration(new_vps, 1);
00436 }
00437
00448 static void SetViewportModeSplitHoriz(void)
00449 {
00450 CViewport new_vps[MAX_NUM_VIEWPORTS];
00451
00452 DebugPrint("Two horizontal viewports set\n");
00453
00454 new_vps[0].X = UI.MapArea.X;
00455 new_vps[0].Y = UI.MapArea.Y;
00456 ClipViewport(new_vps, UI.MapArea.EndX,
00457 UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
00458
00459 new_vps[1].X = UI.MapArea.X;
00460 new_vps[1].Y = new_vps[0].EndY + 1;
00461 ClipViewport(new_vps + 1, UI.MapArea.EndX, UI.MapArea.EndY);
00462
00463 FinishViewportModeConfiguration(new_vps, 2);
00464 }
00465
00477 static void SetViewportModeSplitHoriz3(void)
00478 {
00479 CViewport new_vps[MAX_NUM_VIEWPORTS];
00480
00481 DebugPrint("Horizontal 3-way viewport division set\n");
00482
00483 new_vps[0].X = UI.MapArea.X;
00484 new_vps[0].Y = UI.MapArea.Y;
00485 ClipViewport(new_vps, UI.MapArea.EndX,
00486 UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
00487
00488 new_vps[1].X = UI.MapArea.X;
00489 new_vps[1].Y = new_vps[0].EndY + 1;
00490 ClipViewport(new_vps + 1,
00491 UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
00492 UI.MapArea.EndY);
00493
00494 new_vps[2].X = new_vps[1].EndX + 1;
00495 new_vps[2].Y = new_vps[0].EndY + 1;
00496 ClipViewport(new_vps + 2, UI.MapArea.EndX, UI.MapArea.EndY);
00497
00498 FinishViewportModeConfiguration(new_vps, 3);
00499 }
00500
00511 static void SetViewportModeSplitVert(void)
00512 {
00513 CViewport new_vps[MAX_NUM_VIEWPORTS];
00514
00515 DebugPrint("Two vertical viewports set\n");
00516
00517 new_vps[0].X = UI.MapArea.X;
00518 new_vps[0].Y = UI.MapArea.Y;
00519 ClipViewport(new_vps,
00520 UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
00521 UI.MapArea.EndY);
00522
00523 new_vps[1].X = new_vps[0].EndX + 1;
00524 new_vps[1].Y = UI.MapArea.Y;
00525 ClipViewport(new_vps + 1, UI.MapArea.EndX, UI.MapArea.EndY);
00526
00527 FinishViewportModeConfiguration(new_vps, 2);
00528 }
00529
00540 static void SetViewportModeQuad(void)
00541 {
00542 CViewport new_vps[MAX_NUM_VIEWPORTS];
00543
00544 DebugPrint("Four viewports set\n");
00545
00546 new_vps[0].X = UI.MapArea.X;
00547 new_vps[0].Y = UI.MapArea.Y;
00548 ClipViewport(new_vps,
00549 UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
00550 UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
00551
00552 new_vps[1].X = new_vps[0].EndX + 1;
00553 new_vps[1].Y = UI.MapArea.Y;
00554 ClipViewport(new_vps + 1,
00555 UI.MapArea.EndX,
00556 UI.MapArea.Y + (UI.MapArea.EndY - UI.MapArea.Y + 1) / 2);
00557
00558 new_vps[2].X = UI.MapArea.X;
00559 new_vps[2].Y = new_vps[0].EndY + 1;
00560 ClipViewport(new_vps + 2,
00561 UI.MapArea.X + (UI.MapArea.EndX - UI.MapArea.X + 1) / 2,
00562 UI.MapArea.EndY);
00563
00564 new_vps[3].X = new_vps[1].X;
00565 new_vps[3].Y = new_vps[2].Y;
00566 ClipViewport(new_vps + 3, UI.MapArea.EndX, UI.MapArea.EndY);
00567
00568 FinishViewportModeConfiguration(new_vps, 4);
00569 }
00570
00576 void SetViewportMode(ViewportModeType new_mode)
00577 {
00578 switch (UI.ViewportMode = new_mode) {
00579 case VIEWPORT_SINGLE:
00580 SetViewportModeSingle();
00581 break;
00582 case VIEWPORT_SPLIT_HORIZ:
00583 SetViewportModeSplitHoriz();
00584 break;
00585 case VIEWPORT_SPLIT_HORIZ3:
00586 SetViewportModeSplitHoriz3();
00587 break;
00588 case VIEWPORT_SPLIT_VERT:
00589 SetViewportModeSplitVert();
00590 break;
00591 case VIEWPORT_QUAD:
00592 SetViewportModeQuad();
00593 break;
00594 default:
00595 DebugPrint("trying to set an unknown mode!!\n");
00596 break;
00597 }
00598 }
00599
00608 void CycleViewportMode(int step)
00609 {
00610 int new_mode;
00611
00612 new_mode = UI.ViewportMode + step;
00613 if (new_mode >= NUM_VIEWPORT_MODES) {
00614 new_mode = 0;
00615 }
00616 if (new_mode < 0) {
00617 new_mode = NUM_VIEWPORT_MODES - 1;
00618 }
00619 SetViewportMode((ViewportModeType)new_mode);
00620 }
00621
00625 bool GetMouseScroll(void)
00626 {
00627 return UI.MouseScroll;
00628 }
00629
00635 void SetMouseScroll(bool enabled)
00636 {
00637 UI.MouseScroll = enabled;
00638 }
00639
00643 bool GetKeyScroll()
00644 {
00645 return UI.KeyScroll;
00646 }
00647
00653 void SetKeyScroll(bool enabled)
00654 {
00655 UI.KeyScroll = enabled;
00656 }
00657
00661 bool GetGrabMouse(void)
00662 {
00663 return SdlGetGrabMouse();
00664 }
00665
00671 void SetGrabMouse(bool enabled)
00672 {
00673 ToggleGrabMouse(enabled ? 1 : -1);
00674 }
00675
00679 bool GetLeaveStops(void)
00680 {
00681 return LeaveStops;
00682 }
00683
00689 void SetLeaveStops(bool enabled)
00690 {
00691 LeaveStops = enabled;
00692 }
00693