hedgewars/fGUI.pas
changeset 1 30f2d1037d5d
child 4 bcbd7adb4e4b
equal deleted inserted replaced
0:475c0f2f9d17 1:30f2d1037d5d
       
     1 (*
       
     2  * Hedgewars, a worms-like game
       
     3  * Copyright (c) 2004, 2005 Andrey Korotaev <unC0Rr@gmail.com>
       
     4  *
       
     5  * Distributed under the terms of the BSD-modified licence:
       
     6  *
       
     7  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     8  * of this software and associated documentation files (the "Software"), to deal
       
     9  * with the Software without restriction, including without limitation the
       
    10  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
       
    11  * sell copies of the Software, and to permit persons to whom the Software is
       
    12  * furnished to do so, subject to the following conditions:
       
    13  *
       
    14  * 1. Redistributions of source code must retain the above copyright notice,
       
    15  *    this list of conditions and the following disclaimer.
       
    16  * 2. Redistributions in binary form must reproduce the above copyright notice,
       
    17  *    this list of conditions and the following disclaimer in the documentation
       
    18  *    and/or other materials provided with the distribution.
       
    19  * 3. The name of the author may not be used to endorse or promote products
       
    20  *    derived from this software without specific prior written permission.
       
    21  *
       
    22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
       
    23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
       
    24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
       
    25  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    27  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
       
    28  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
       
    29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
       
    30  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
       
    31  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    32  *)
       
    33 
       
    34 unit fGUI;
       
    35 interface
       
    36 uses Windows;
       
    37 
       
    38 procedure ProcessMessages;
       
    39 function GetWindowTextStr(hwnd: HWND): string;
       
    40 procedure DoControlPress(wParam: WPARAM;  lParam: LPARAM);
       
    41 procedure DoDrawButton(idCtl: UINT; lpmis: PDrawItemStruct);
       
    42 procedure LoadGraphics;
       
    43 procedure DoDestroy;
       
    44 procedure DoCreateControls;
       
    45 procedure DoCreateMainWindow;
       
    46 
       
    47 
       
    48 var hwndMain,hwndOptions: HWND;
       
    49 var isTerminated: boolean = false;
       
    50 var //main menu
       
    51     bitmap       ,optbmp        ,localbmp      ,netbmp      ,demobmp    ,exitbmp      ,setsbmp      : HBITMAP;
       
    52     BackGroundDC ,OptBGroundDC  ,DCLocalGame   ,DCNetGame   ,DCDemoPlay ,DCExitGame   ,DCSettings   : HDC;
       
    53                   HLocalGameBtn ,HNetGameBtm ,HDemoBtn   ,HExitGameBtn ,HSettingsBtn, HBGStatic : HWND;
       
    54     //other
       
    55     HNetIPEdit,HNetIPStatic: HWND;
       
    56     HNetNameEdit,HNetNameStatic,HNetConnectionStatic: HWND;
       
    57     HNetJoinBtn,HNetBeginBtn,HNetBackBtn:HWND;
       
    58     HDemoList,HDemoBeginBtn,HDemoBackBtn,HDemoAllBtn:HWND;
       
    59     HSetResEdit,HFullScrCheck,HSetDemoCheck,HSetSndCheck,HSetSaveBtn,HSetBackBtn,HSetShowTeamOptionsBtn:HWND;
       
    60     scrx, scry: real;
       
    61 
       
    62 
       
    63 implementation
       
    64 uses fConsts, Messages, SysUtils, uConsts, fGame, fNet, fMisc, fOptionsGUI;
       
    65 
       
    66 function GetWindowTextStr(hwnd: HWND): string;
       
    67 var i: integer;
       
    68 begin
       
    69 i:= GetWindowTextLength(hwnd);
       
    70 SetLength(Result, i);
       
    71 GetWindowText(hwnd, PChar(Result), Succ(i))
       
    72 end;
       
    73 
       
    74 
       
    75 procedure ProcessMessages;
       
    76 var Message: Windows.MSG;
       
    77 begin
       
    78 if PeekMessage(Message,0,0,0,PM_REMOVE) then
       
    79   if Message.message <> WM_QUIT then
       
    80     begin
       
    81     TranslateMessage(Message);
       
    82     DispatchMessage(Message)
       
    83     end else isTerminated:= true
       
    84 end;
       
    85 
       
    86 procedure HideMain;
       
    87 begin
       
    88 ShowWindow(HLocalGameBtn,SW_HIDE);
       
    89 ShowWindow(HNetGameBtm,SW_HIDE);
       
    90 ShowWindow(HDemoBtn,SW_HIDE);
       
    91 ShowWindow(HSettingsBtn,SW_HIDE);
       
    92 ShowWindow(HExitGameBtn,SW_HIDE)
       
    93 end;
       
    94 
       
    95 procedure ShowMain;
       
    96 begin
       
    97 ShowWindow(HLocalGameBtn,SW_SHOW);
       
    98 ShowWindow(HNetGameBtm,SW_SHOW);
       
    99 ShowWindow(HDemoBtn,SW_SHOW);
       
   100 ShowWindow(HSettingsBtn,SW_SHOW);
       
   101 ShowWindow(HExitGameBtn,SW_SHOW);
       
   102 SetFocus(HLocalGameBtn)
       
   103 end;
       
   104 
       
   105 
       
   106 
       
   107 procedure ShowNetGameMenu;
       
   108 begin
       
   109 HideMain;
       
   110 ShowWindow(HNetIPStatic,SW_SHOW);
       
   111 ShowWindow(HNetIPEdit,SW_SHOW);
       
   112 ShowWindow(HNetNameStatic,SW_SHOW);
       
   113 ShowWindow(HNetNameEdit,SW_SHOW);  
       
   114 ShowWindow(HNetConnectionStatic,SW_SHOW);
       
   115 ShowWindow(HNetJoinBtn,SW_SHOW);
       
   116 ShowWindow(HNetBeginBtn,SW_SHOW);
       
   117 ShowWindow(HNetBackBtn,SW_SHOW);
       
   118 SetFocus(HNetJoinBtn)
       
   119 end;
       
   120 
       
   121 
       
   122 procedure ShowMainFromNetMenu;
       
   123 begin
       
   124 ShowWindow(HNetIPEdit,SW_HIDE);
       
   125 ShowWindow(HNetIPStatic,SW_HIDE);
       
   126 ShowWindow(HNetNameEdit,SW_HIDE);
       
   127 ShowWindow(HNetNameStatic,SW_HIDE);
       
   128 ShowWindow(HNetConnectionStatic,SW_HIDE);
       
   129 ShowWindow(HNetJoinBtn,SW_HIDE);
       
   130 ShowWindow(HNetBeginBtn,SW_HIDE);
       
   131 ShowWindow(HNetBackBtn,SW_HIDE);
       
   132 ShowMain
       
   133 end;
       
   134 
       
   135 
       
   136 procedure ShowDemoMenu;
       
   137 var i: integer;
       
   138     sr: TSearchRec;
       
   139 begin
       
   140 SendMessage(HDemoList, LB_RESETCONTENT, 0, 0);
       
   141 i:= FindFirst(format('%s*.hwd_%d',[Pathz[ptDemos], cNetProtoVersion]), faAnyFile and not faDirectory, sr);
       
   142 while i = 0 do
       
   143       begin
       
   144       SendMessage(HDemoList, LB_ADDSTRING, 0, LPARAM(PChar(sr.Name)));
       
   145       i:= FindNext(sr)
       
   146       end;
       
   147 FindClose(sr);
       
   148 
       
   149 HideMain;
       
   150 
       
   151 ShowWindow(HDemoList,SW_SHOW);
       
   152 ShowWindow(HDemoBeginBtn,SW_SHOW);
       
   153 ShowWindow(HDemoAllBtn,SW_SHOW);
       
   154 ShowWindow(HDemoBackBtn,SW_SHOW);
       
   155 SetFocus(HDemoList)
       
   156 end;
       
   157 
       
   158 procedure ShowMainFromDemoMenu;
       
   159 begin
       
   160 ShowWindow(HDemoList,SW_HIDE);
       
   161 ShowWindow(HDemoBeginBtn,SW_HIDE);
       
   162 ShowWindow(HDemoAllBtn,SW_HIDE);
       
   163 ShowWindow(HDemoBackBtn,SW_HIDE);
       
   164 ShowMain
       
   165 end;
       
   166 
       
   167 procedure ShowSettingsMenu;
       
   168 begin
       
   169 HideMain;
       
   170 ShowWindow(HSetResEdit,SW_SHOW);
       
   171 ShowWindow(HFullScrCheck,SW_SHOW);
       
   172 ShowWindow(HSetDemoCheck,SW_SHOW);
       
   173 ShowWindow(HSetSndCheck,SW_SHOW);
       
   174 ShowWindow(HSetSaveBtn,SW_SHOW);
       
   175 ShowWindow(HSetBackBtn,SW_SHOW);
       
   176 ShowWindow(HSetShowTeamOptionsBtn,SW_SHOW);
       
   177 SetFocus(HSetResEdit)
       
   178 end;
       
   179 
       
   180 procedure ShowMainFromSettings;
       
   181 begin
       
   182 ShowWindow(HSetResEdit,SW_HIDE);
       
   183 ShowWindow(HFullScrCheck,SW_HIDE);
       
   184 ShowWindow(HSetDemoCheck,SW_HIDE);
       
   185 ShowWindow(HSetSndCheck,SW_HIDE);
       
   186 ShowWindow(HSetSaveBtn,SW_HIDE);
       
   187 ShowWindow(HSetBackBtn,SW_HIDE);
       
   188 ShowWindow(HSetShowTeamOptionsBtn,SW_HIDE);
       
   189 ShowMain
       
   190 end;
       
   191 
       
   192 procedure DoControlPress(wParam: WPARAM;  lParam: LPARAM);
       
   193 begin
       
   194 case LOWORD(wParam) of
       
   195     cLocalGameBtn : StartLocalGame;
       
   196     cNetGameBtn   : ShowNetGameMenu;
       
   197     cDemoBtn      : ShowDemoMenu;
       
   198     cSettingsBtn  : ShowSettingsMenu;
       
   199     cExitGameBtn  : Halt;
       
   200     cNetBackBtn   : ShowMainFromNetMenu;
       
   201     cNetJoinBtn   : NetConnect;
       
   202     cNetBeginBtn  : StartNetGame;
       
   203     cDemoBackBtn  : ShowMainFromDemoMenu;
       
   204     cDemoAllBtn   : MessageBeep(0);//PlayAllDemos;
       
   205     cDemoBeginBtn : StartDemoView;
       
   206     cSetSaveBtn   : SaveSettings;
       
   207     cSetBackBtn   : ShowMainFromSettings;
       
   208     cSetShowTeamOptions : ShowOptionsWindow;
       
   209     end
       
   210 end;
       
   211 
       
   212 procedure DoDrawButton(idCtl: UINT; lpmis: PDrawItemStruct);
       
   213 begin
       
   214 case lpmis.CtlID of
       
   215   cLocalGameBtn: StretchBlt(lpmis.hDC,0,0,trunc(309*scrx),trunc(22*scry),DCLocalGame,0,0,309,22,SRCCOPY);
       
   216     cNetGameBtn: StretchBlt(lpmis.hDC,0,0,trunc(272*scrx),trunc(22*scry),DCNetGame  ,0,0,272,22,SRCCOPY);
       
   217        cDemoBtn: StretchBlt(lpmis.hDC,0,0,trunc(181*scrx),trunc(22*scry),DCDemoPlay ,0,0,181,22,SRCCOPY);
       
   218    cSettingsBtn: StretchBlt(lpmis.hDC,0,0,trunc(147*scrx),trunc(22*scry),DCSettings ,0,0,147,22,SRCCOPY);
       
   219    cExitGameBtn: StretchBlt(lpmis.hDC,0,0,trunc(272*scrx),trunc(22*scry),DCExitGame ,0,0,272,22,SRCCOPY);
       
   220       cBGStatic: StretchBlt(lpmis.hDC,0,0,trunc(1024*scrx),trunc(768*scry),BackGroundDC,0,0,1024,768,SRCCOPY);
       
   221    cOptBGStatic: StretchBlt(lpmis.hDC,0,0,trunc(1024*scrx),trunc(768*scry),OptBGroundDC,0,0,1024,768,SRCCOPY);
       
   222      end
       
   223 end;
       
   224 
       
   225 procedure LoadGraphics;
       
   226 begin
       
   227 scrx :=  GetSystemMetrics(SM_CXSCREEN)/1024;
       
   228 scry :=  GetSystemMetrics(SM_CYSCREEN)/768;
       
   229 LoadOwnerBitmap(bitmap, cGFXPath + 'front.bmp',      BackGroundDC,hwndMain);
       
   230 LoadOwnerBitmap(optbmp, cGFXPath + 'TeamSettings.bmp',OptBGroundDC,hwndOptions);
       
   231 LoadOwnerBitmap(localbmp,cGFXPath + 'startlocal.bmp', DCLocalGame,cLocalGameBtn);
       
   232 LoadOwnerBitmap(netbmp,  cGFXPath + 'startnet.bmp',   DCNetGame,  cNetGameBtn);
       
   233 LoadOwnerBitmap(demobmp, cGFXPath + 'playdemo.bmp',   DCDemoPlay, cDemoBtn);
       
   234 LoadOwnerBitmap(setsbmp, cGFXPath + 'settings.bmp',   DCSettings, cSettingsBtn);
       
   235 LoadOwnerBitmap(exitbmp, cGFXPath + 'exit.bmp',       DCExitGame, cExitGameBtn);
       
   236 end;
       
   237 
       
   238 procedure DoDestroy;
       
   239 begin
       
   240 DeleteObject(localbmp);
       
   241 DeleteObject(optbmp);
       
   242 DeleteObject(bitmap);
       
   243 DeleteObject(netbmp);
       
   244 DeleteObject(demobmp);
       
   245 DeleteObject(setsbmp);
       
   246 DeleteObject(bitmap);
       
   247 DeleteDC(DCLocalGame);
       
   248 DeleteDC(DCNetGame);
       
   249 DeleteDC(DCDemoPlay);
       
   250 DeleteDC(DCSettings);
       
   251 DeleteDC(BackGroundDC);
       
   252 DeleteDC(OptBGroundDC)
       
   253 end;
       
   254 
       
   255 procedure DoCreateControls;
       
   256 begin
       
   257 HBGStatic      := CreateWindow('STATIC','bg image static'  ,WS_CHILD or WS_VISIBLE or SS_OWNERDRAW, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), hwndMain, cBGStatic, HInstance, nil);
       
   258 /// main menu ///
       
   259 HLocalGameBtn  := CreateWindow('button','local game button',WS_CHILD or WS_VISIBLE or BS_OWNERDRAW, trunc(510 * scrx), trunc(400 *scry), trunc(309* scrx) , trunc(22*scry) , hwndMain , cLocalGameBtn, HInstance,  nil );
       
   260 HNetGameBtm    := CreateWindow('button',  'net game button',WS_CHILD or WS_VISIBLE or BS_OWNERDRAW, trunc(530 * scrx), trunc(450 *scry), trunc(272* scrx) , trunc(22*scry) , hwndMain ,   cNetGameBtn, HInstance,  nil );
       
   261 HDemoBtn       := CreateWindow('button', 'play demo button',WS_CHILD or WS_VISIBLE or BS_OWNERDRAW, trunc(570 * scrx), trunc(500 *scry), trunc(181* scrx) , trunc(22*scry) , hwndMain ,      cDemoBtn, HInstance,  nil );
       
   262 HSettingsBtn   := CreateWindow('button', 'settings  button',WS_CHILD or WS_VISIBLE or BS_OWNERDRAW, trunc(590 * scrx), trunc(550 *scry), trunc(147* scrx) , trunc(22*scry) , hwndMain ,  cSettingsBtn, HInstance,  nil );
       
   263 HExitGameBtn   := CreateWindow('button', 'exit game button',WS_CHILD or WS_VISIBLE or BS_OWNERDRAW, trunc(530 * scrx), trunc(600 *scry), trunc(272* scrx) , trunc(22*scry) , hwndMain ,  cExitGameBtn, HInstance,  nil );
       
   264 /// local menu ///
       
   265 /// net menu ///
       
   266 HNetIPEdit     := CreateWindow('EDIT', '255.255.255.255'   ,WS_CHILD or WS_TABSTOP,                     trunc(570* scrx), trunc(400*scry) , 150 , 16 , hwndMain ,  cNetIpEdit,     HInstance,  nil );
       
   267 HNetIPStatic   := CreateWindow('STATIC','IP :'             ,WS_CHILD or SS_SIMPLE,                      trunc(520* scrx), trunc(400*scry) , 50  , 16 , hwndMain ,  cNetIpStatic,   HInstance,  nil );
       
   268 HNetNameEdit   := CreateWindow('EDIT', 'Hedgewarrior'      ,WS_CHILD or WS_TABSTOP,                     trunc(570* scrx), trunc(420*scry) , 150 , 16 , hwndMain ,  cNetNameEdit,   HInstance,  nil );
       
   269 HNetNameStatic := CreateWindow('STATIC','Name : '          ,WS_CHILD or SS_SIMPLE,                      trunc(520* scrx), trunc(420*scry) , 50  , 16 , hwndMain ,  cNetNameStatic, HInstance,  nil );
       
   270 HNetConnectionStatic
       
   271                := CreateWindow('STATIC','not connected'    ,WS_CHILD,                                   trunc(520* scrx), trunc(450*scry) , 90 , 16 , hwndMain ,  cNetConnStatic,  HInstance,  nil );
       
   272 HNetJoinBtn    := CreateWindow('BUTTON','Join Game'        ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(520* scrx), trunc(550*scry) , 90 , 20 , hwndMain ,  cNetJoinBtn,     HInstance,  nil );
       
   273 HNetBeginBtn   := CreateWindow('BUTTON','Begin Game'       ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(520* scrx), trunc(575*scry) , 90 , 20 , hwndMain ,  cNetBeginBtn,    HInstance,  nil );
       
   274 HNetBackBtn    := CreateWindow('BUTTON','Back'             ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(520* scrx), trunc(600*scry) , 90 , 20 , hwndMain ,  cNetBackBtn,     HInstance,  nil );
       
   275 /// demo menu ///
       
   276 HDemoList      := CreateWindow('LISTBOX',''                ,WS_CHILD or WS_TABSTOP, trunc(530* scrx),   trunc(400*scry) , trunc(200* scrx), trunc(200*scry), hwndMain,  cDemoList, HInstance,  nil );
       
   277 HDemoBeginBtn  := CreateWindow('BUTTON','Play demo'        ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(750* scrx), trunc(400*scry) , 100 , 20 , hwndMain ,  cDemoBeginBtn,   HInstance,  nil );
       
   278 HDemoAllBtn    := CreateWindow('BUTTON','Play all demos'   ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(750* scrx), trunc(425*scry) , 100 , 20 , hwndMain ,  cDemoAllBtn,     HInstance,  nil );
       
   279 HDemoBackBtn   := CreateWindow('BUTTON','Back'             ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(750* scrx), trunc(450*scry) , 100 , 20 , hwndMain ,  cDemoBackBtn,    HInstance,  nil );
       
   280 
       
   281 /// settings menu ///
       
   282 HSetResEdit    := CreateWindow('COMBOBOX', ''              ,WS_CHILD or CBS_DROPDOWNLIST or WS_TABSTOP, trunc(530* scrx), trunc(420*scry) , 150 , 100 , hwndMain ,  cSetResEdit,   HInstance,  nil );
       
   283 
       
   284 SendMessage(HSetResEdit, CB_ADDSTRING, 0, LPARAM(PChar('640x480')));
       
   285 SendMessage(HSetResEdit, CB_ADDSTRING, 0, LPARAM(PChar('800x600')));
       
   286 SendMessage(HSetResEdit, CB_ADDSTRING, 0, LPARAM(PChar('1024x768')));
       
   287 SendMessage(HSetResEdit, CB_ADDSTRING, 0, LPARAM(PChar('1280x1024')));
       
   288 
       
   289 HFullScrCheck  := CreateWindow('BUTTON','Fullscreen'       ,WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP,  trunc(530* scrx), trunc(450*scry) , 110 , 20 , hwndMain ,  cSetFScrCheck,  HInstance,  nil );
       
   290 HSetDemoCheck  := CreateWindow('BUTTON','Record Demo'      ,WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP,  trunc(530* scrx), trunc(475*scry) , 110 , 20 , hwndMain ,  cSetDemoCheck,  HInstance,  nil );
       
   291 HSetSndCheck   := CreateWindow('BUTTON','Enable Sound'     ,WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP,  trunc(530* scrx), trunc(500*scry) , 110 , 20 , hwndMain ,  cSetSndCheck,   HInstance,  nil );
       
   292 HSetSaveBtn    := CreateWindow('BUTTON','Save Settings'    ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(530* scrx), trunc(580*scry) , 100 , 20 , hwndMain ,  cSetSaveBtn,    HInstance,  nil );
       
   293 HSetBackBtn    := CreateWindow('BUTTON','Back'             ,WS_CHILD or BS_FLAT or WS_TABSTOP,          trunc(730* scrx), trunc(580*scry) , 90  , 20 , hwndMain ,  cSetBackBtn,    HInstance,  nil );
       
   294 HSetShowTeamOptionsBtn    := CreateWindow('BUTTON','Show Team Options' ,WS_CHILD or BS_FLAT or WS_TABSTOP, trunc(700* scrx), trunc(420*scry) , 140  , 20 , hwndMain ,  cSetShowTeamOptions,    HInstance,  nil );
       
   295 end;
       
   296 
       
   297 procedure DoCreateMainWindow;
       
   298 var  wc: WNDCLASS;
       
   299 begin
       
   300 FillChar(wc, sizeof(wc), 0);
       
   301 wc.style         := CS_VREDRAW or CS_HREDRAW;
       
   302 wc.hbrBackground := COLOR_BACKGROUND;
       
   303 wc.lpfnWndProc   := @MainWndProc;
       
   304 wc.hInstance     := hInstance;
       
   305 wc.lpszClassName := cAppName;
       
   306 wc.hCursor := LoadCursor(hwndMain,IDC_ARROW);
       
   307 if RegisterClass(wc) = 0 then begin MessageBox(0,'RegisterClass failed for main wnd','Failed',MB_OK); halt; end;
       
   308 hwndMain := CreateWindowEx( 0, cAppName, cAppTitle, WS_POPUP,
       
   309 	                    0, 0,
       
   310 	                    GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
       
   311                             0, 0, hInstance, nil);
       
   312 
       
   313 ShowWindow(hwndMain,SW_SHOW);
       
   314 UpdateWindow(hwndMain)
       
   315 end;
       
   316 
       
   317 
       
   318 end.