main_gui.cpp

Go to the documentation of this file.
00001 /* $Id: main_gui.cpp 14422 2008-09-30 20:51:04Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "currency.h"
00008 #include "spritecache.h"
00009 #include "gui.h"
00010 #include "window_gui.h"
00011 #include "window_func.h"
00012 #include "textbuf_gui.h"
00013 #include "viewport_func.h"
00014 #include "command_func.h"
00015 #include "news_gui.h"
00016 #include "console_gui.h"
00017 #include "waypoint.h"
00018 #include "genworld.h"
00019 #include "transparency_gui.h"
00020 #include "date_func.h"
00021 #include "functions.h"
00022 #include "sound_func.h"
00023 #include "transparency.h"
00024 #include "strings_func.h"
00025 #include "zoom_func.h"
00026 #include "string_func.h"
00027 #include "company_base.h"
00028 #include "company_func.h"
00029 #include "company_gui.h"
00030 #include "settings_type.h"
00031 #include "toolbar_gui.h"
00032 #include "statusbar_gui.h"
00033 #include "variables.h"
00034 #include "tilehighlight_func.h"
00035 
00036 #include "network/network.h"
00037 #include "network/network_func.h"
00038 #include "network/network_gui.h"
00039 
00040 #include "table/sprites.h"
00041 #include "table/strings.h"
00042 
00043 static int _rename_id = 1;
00044 static int _rename_what = -1;
00045 
00046 void CcGiveMoney(bool success, TileIndex tile, uint32 p1, uint32 p2)
00047 {
00048 #ifdef ENABLE_NETWORK
00049   if (!success || !_settings_game.economy.give_money) return;
00050 
00051   char msg[20];
00052   /* Inform the company of the action of one of it's clients (controllers). */
00053   snprintf(msg, sizeof(msg), "%d", p1);
00054 
00055   if (!_network_server) {
00056     NetworkClientSendChat(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, p2, msg);
00057   } else {
00058     NetworkServerSendChat(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, p2, msg, NETWORK_SERVER_INDEX);
00059   }
00060 #endif /* ENABLE_NETWORK */
00061 }
00062 
00063 void HandleOnEditText(const char *str)
00064 {
00065   _cmd_text = str;
00066 
00067   switch (_rename_what) {
00068 #ifdef ENABLE_NETWORK
00069   case 3: { // Give money, you can only give money in excess of loan
00070     const Company *c = GetCompany(_current_company);
00071     Money money = min(c->money - c->current_loan, (Money)(atoi(str) / _currency->rate));
00072 
00073     uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0
00074 
00075     /* Give 'id' the money, and substract it from ourself */
00076     DoCommandP(0, money_c, _rename_id, CcGiveMoney, CMD_GIVE_MONEY | CMD_MSG(STR_INSUFFICIENT_FUNDS));
00077   } break;
00078 #endif /* ENABLE_NETWORK */
00079     default: NOT_REACHED();
00080   }
00081 
00082   _rename_id = _rename_what = -1;
00083 }
00084 
00096 bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, ViewportHighlightMode mode, PlaceProc *placeproc)
00097 {
00098   if (w->IsWidgetDisabled(widget)) return false;
00099 
00100   SndPlayFx(SND_15_BEEP);
00101   w->SetDirty();
00102 
00103   if (w->IsWidgetLowered(widget)) {
00104     ResetObjectToPlace();
00105     return false;
00106   }
00107 
00108   SetObjectToPlace(cursor, PAL_NONE, mode, w->window_class, w->window_number);
00109   w->LowerWidget(widget);
00110   _place_proc = placeproc;
00111   return true;
00112 }
00113 
00114 
00115 void CcPlaySound10(bool success, TileIndex tile, uint32 p1, uint32 p2)
00116 {
00117   if (success) SndPlayTileFx(SND_12_EXPLOSION, tile);
00118 }
00119 
00120 #ifdef ENABLE_NETWORK
00121 void ShowNetworkGiveMoneyWindow(CompanyID company)
00122 {
00123   _rename_id = company;
00124   _rename_what = 3;
00125   ShowQueryString(STR_EMPTY, STR_NETWORK_GIVE_MONEY_CAPTION, 30, 180, NULL, CS_NUMERAL, QSF_NONE);
00126 }
00127 #endif /* ENABLE_NETWORK */
00128 
00129 
00130 /* Zooms a viewport in a window in or out */
00131 /* No button handling or what so ever */
00132 bool DoZoomInOutWindow(int how, Window *w)
00133 {
00134   ViewPort *vp;
00135 
00136   assert(w != NULL);
00137   vp = w->viewport;
00138 
00139   switch (how) {
00140     case ZOOM_IN:
00141       if (vp->zoom == ZOOM_LVL_MIN) return false;
00142       vp->zoom = (ZoomLevel)((int)vp->zoom - 1);
00143       vp->virtual_width >>= 1;
00144       vp->virtual_height >>= 1;
00145 
00146       w->viewport->scrollpos_x += vp->virtual_width >> 1;
00147       w->viewport->scrollpos_y += vp->virtual_height >> 1;
00148       w->viewport->dest_scrollpos_x = w->viewport->scrollpos_x;
00149       w->viewport->dest_scrollpos_y = w->viewport->scrollpos_y;
00150       break;
00151     case ZOOM_OUT:
00152       if (vp->zoom == ZOOM_LVL_MAX) return false;
00153       vp->zoom = (ZoomLevel)((int)vp->zoom + 1);
00154 
00155       w->viewport->scrollpos_x -= vp->virtual_width >> 1;
00156       w->viewport->scrollpos_y -= vp->virtual_height >> 1;
00157       w->viewport->dest_scrollpos_x = w->viewport->scrollpos_x;
00158       w->viewport->dest_scrollpos_y = w->viewport->scrollpos_y;
00159 
00160       vp->virtual_width <<= 1;
00161       vp->virtual_height <<= 1;
00162       break;
00163   }
00164   if (vp != NULL) { // the vp can be null when how == ZOOM_NONE
00165     vp->virtual_left = w->viewport->scrollpos_x;
00166     vp->virtual_top = w->viewport->scrollpos_y;
00167   }
00168   w->SetDirty();
00169   /* Update the windows that have zoom-buttons to perhaps disable their buttons */
00170   InvalidateThisWindowData(w);
00171   return true;
00172 }
00173 
00174 void ZoomInOrOutToCursorWindow(bool in, Window *w)
00175 {
00176   assert(w != NULL);
00177 
00178   if (_game_mode != GM_MENU) {
00179     ViewPort *vp = w->viewport;
00180     if ((in && vp->zoom == ZOOM_LVL_MIN) || (!in && vp->zoom == ZOOM_LVL_MAX))
00181       return;
00182 
00183     Point pt = GetTileZoomCenterWindow(in,w);
00184     if (pt.x != -1) {
00185       ScrollWindowTo(pt.x, pt.y, w, true);
00186 
00187       DoZoomInOutWindow(in ? ZOOM_IN : ZOOM_OUT, w);
00188     }
00189   }
00190 }
00191 
00192 extern void UpdateAllStationVirtCoord();
00193 
00194 struct MainWindow : Window
00195 {
00196   MainWindow(int width, int height) : Window(0, 0, width, height, WC_MAIN_WINDOW, NULL)
00197   {
00198     InitializeWindowViewport(this, 0, 0, width, height, TileXY(32, 32), ZOOM_LVL_VIEWPORT);
00199   }
00200 
00201   virtual void OnPaint()
00202   {
00203     this->DrawViewport();
00204     if (_game_mode == GM_MENU) {
00205       int off_x = _screen.width / 2;
00206 
00207       DrawSprite(SPR_OTTD_O, PAL_NONE, off_x - 120, 50);
00208       DrawSprite(SPR_OTTD_P, PAL_NONE, off_x -  86, 50);
00209       DrawSprite(SPR_OTTD_E, PAL_NONE, off_x -  53, 50);
00210       DrawSprite(SPR_OTTD_N, PAL_NONE, off_x -  22, 50);
00211 
00212       DrawSprite(SPR_OTTD_T, PAL_NONE, off_x +  34, 50);
00213       DrawSprite(SPR_OTTD_T, PAL_NONE, off_x +  65, 50);
00214       DrawSprite(SPR_OTTD_D, PAL_NONE, off_x +  96, 50);
00215     }
00216   }
00217 
00218   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00219   {
00220     switch (keycode) {
00221       case 'Q' | WKC_CTRL:
00222       case 'Q' | WKC_META:
00223         HandleExitGameRequest();
00224         return ES_HANDLED;
00225     }
00226 
00227     /* Disable all key shortcuts, except quit shortcuts when
00228     * generating the world, otherwise they create threading
00229     * problem during the generating, resulting in random
00230     * assertions that are hard to trigger and debug */
00231     if (IsGeneratingWorld()) return ES_NOT_HANDLED;
00232 
00233     if (keycode == WKC_BACKQUOTE) {
00234       IConsoleSwitch();
00235       return ES_HANDLED;
00236     }
00237 
00238     if (keycode == ('B' | WKC_CTRL)) {
00239       extern bool _draw_bounding_boxes;
00240       _draw_bounding_boxes = !_draw_bounding_boxes;
00241       MarkWholeScreenDirty();
00242       return ES_HANDLED;
00243     }
00244 
00245     if (_game_mode == GM_MENU) return ES_NOT_HANDLED;
00246 
00247     switch (keycode) {
00248       case 'C':
00249       case 'Z': {
00250         Point pt = GetTileBelowCursor();
00251         if (pt.x != -1) {
00252           if (keycode == 'Z') MaxZoomInOut(ZOOM_IN, this);
00253           ScrollMainWindowTo(pt.x, pt.y);
00254         }
00255         break;
00256       }
00257 
00258       case WKC_ESC: ResetObjectToPlace(); break;
00259       case WKC_DELETE: DeleteNonVitalWindows(); break;
00260       case WKC_DELETE | WKC_SHIFT: DeleteAllNonVitalWindows(); break;
00261       case 'R' | WKC_CTRL: MarkWholeScreenDirty(); break;
00262 
00263 #if defined(_DEBUG)
00264       case '0' | WKC_ALT: // Crash the game
00265         *(byte*)0 = 0;
00266         break;
00267 
00268       case '1' | WKC_ALT: // Gimme money
00269         /* Server can not cheat in advertise mode either! */
00270         if (!_networking || !_network_server || !_settings_client.network.server_advertise)
00271           DoCommandP(0, 10000000, 0, NULL, CMD_MONEY_CHEAT);
00272         break;
00273 
00274       case '2' | WKC_ALT: // Update the coordinates of all station signs
00275         UpdateAllStationVirtCoord();
00276         break;
00277 #endif
00278 
00279       case '1' | WKC_CTRL:
00280       case '2' | WKC_CTRL:
00281       case '3' | WKC_CTRL:
00282       case '4' | WKC_CTRL:
00283       case '5' | WKC_CTRL:
00284       case '6' | WKC_CTRL:
00285       case '7' | WKC_CTRL:
00286       case '8' | WKC_CTRL:
00287       case '9' | WKC_CTRL:
00288         /* Transparency toggle hot keys */
00289         ToggleTransparency((TransparencyOption)(keycode - ('1' | WKC_CTRL)));
00290         MarkWholeScreenDirty();
00291         break;
00292 
00293       case '1' | WKC_CTRL | WKC_SHIFT:
00294       case '2' | WKC_CTRL | WKC_SHIFT:
00295       case '3' | WKC_CTRL | WKC_SHIFT:
00296       case '4' | WKC_CTRL | WKC_SHIFT:
00297       case '5' | WKC_CTRL | WKC_SHIFT:
00298       case '6' | WKC_CTRL | WKC_SHIFT:
00299       case '7' | WKC_CTRL | WKC_SHIFT:
00300       case '8' | WKC_CTRL | WKC_SHIFT:
00301         /* Invisibility toggle hot keys */
00302         ToggleInvisibilityWithTransparency((TransparencyOption)(keycode - ('1' | WKC_CTRL | WKC_SHIFT)));
00303         MarkWholeScreenDirty();
00304         break;
00305 
00306       case 'X' | WKC_CTRL:
00307         ShowTransparencyToolbar();
00308         break;
00309 
00310       case 'X':
00311         ResetRestoreAllTransparency();
00312         break;
00313 
00314 #ifdef ENABLE_NETWORK
00315       case WKC_RETURN: case 'T': // smart chat; send to team if any, otherwise to all
00316         if (_networking) {
00317           const NetworkClientInfo *cio = NetworkFindClientInfoFromIndex(_network_own_client_index);
00318           bool teamchat = false;
00319 
00320           if (cio == NULL) break;
00321 
00322           /* Only companies actually playing can speak to team. Eg spectators cannot */
00323           if (_settings_client.gui.prefer_teamchat && IsValidCompanyID(cio->client_playas)) {
00324             const NetworkClientInfo *ci;
00325             FOR_ALL_ACTIVE_CLIENT_INFOS(ci) {
00326               if (ci->client_playas == cio->client_playas && ci != cio) {
00327                 teamchat = true;
00328                 break;
00329               }
00330             }
00331           }
00332 
00333           ShowNetworkChatQueryWindow(teamchat ? DESTTYPE_TEAM : DESTTYPE_BROADCAST, cio->client_playas);
00334         }
00335         break;
00336 
00337       case WKC_SHIFT | WKC_RETURN: case WKC_SHIFT | 'T': // send text message to all clients
00338         if (_networking) ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0);
00339         break;
00340 
00341       case WKC_CTRL | WKC_RETURN: case WKC_CTRL | 'T': // send text to all team mates
00342         if (_networking) {
00343           const NetworkClientInfo *cio = NetworkFindClientInfoFromIndex(_network_own_client_index);
00344           if (cio == NULL) break;
00345 
00346           ShowNetworkChatQueryWindow(DESTTYPE_TEAM, cio->client_playas);
00347         }
00348         break;
00349 #endif
00350 
00351       default: return ES_NOT_HANDLED;
00352     }
00353     return ES_HANDLED;
00354   }
00355 
00356   virtual void OnScroll(Point delta)
00357   {
00358     ViewPort *vp = IsPtInWindowViewport(this, _cursor.pos.x, _cursor.pos.y);
00359 
00360     if (vp == NULL) {
00361       _cursor.fix_at = false;
00362       _scrolling_viewport = false;
00363     }
00364 
00365     this->viewport->scrollpos_x += ScaleByZoom(delta.x, vp->zoom);
00366     this->viewport->scrollpos_y += ScaleByZoom(delta.y, vp->zoom);
00367     this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x;
00368     this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y;
00369   };
00370 
00371   virtual void OnMouseWheel(int wheel)
00372   {
00373     ZoomInOrOutToCursorWindow(wheel < 0, this);
00374   }
00375 
00376   virtual void OnInvalidateData(int data)
00377   {
00378     /* Forward the message to the appropiate toolbar (ingame or scenario editor) */
00379     InvalidateWindowData(WC_MAIN_TOOLBAR, 0, data);
00380   }
00381 };
00382 
00383 
00384 void ShowSelectGameWindow();
00385 
00386 void SetupColorsAndInitialWindow()
00387 {
00388   for (uint i = 0; i != 16; i++) {
00389     const byte *b = GetNonSprite(PALETTE_RECOLOR_START + i, ST_RECOLOUR);
00390 
00391     assert(b);
00392     memcpy(_colour_gradient[i], b + 0xC6, sizeof(_colour_gradient[i]));
00393   }
00394 
00395   new MainWindow(_screen.width, _screen.height);
00396 
00397   /* XXX: these are not done */
00398   switch (_game_mode) {
00399     default: NOT_REACHED();
00400     case GM_MENU:
00401       ShowSelectGameWindow();
00402       break;
00403 
00404     case GM_NORMAL:
00405     case GM_EDITOR:
00406       ShowVitalWindows();
00407       break;
00408   }
00409 }
00410 
00411 void ShowVitalWindows()
00412 {
00413   AllocateToolbar();
00414 
00415   /* Status bad only for normal games */
00416   if (_game_mode == GM_EDITOR) return;
00417 
00418   ShowStatusBar();
00419 }
00420 
00425 void GameSizeChanged()
00426 {
00427   _cur_resolution.width  = _screen.width;
00428   _cur_resolution.height = _screen.height;
00429   ScreenSizeChanged();
00430   RelocateAllWindows(_screen.width, _screen.height);
00431   MarkWholeScreenDirty();
00432 }

Generated on Fri Nov 21 19:01:33 2008 for openttd by  doxygen 1.5.6