truelight@0: #include "stdafx.h" truelight@0: #include "ttd.h" truelight@0: truelight@0: #include "window.h" truelight@0: #include "gui.h" truelight@0: #include "viewport.h" truelight@0: #include "gfx.h" truelight@0: #include "station.h" truelight@0: #include "command.h" truelight@0: #include "player.h" truelight@0: #include "town.h" tron@337: #include "sound.h" truelight@0: truelight@0: #include "hal.h" // Fios items truelight@0: truelight@0: bool _query_string_active; truelight@0: static void SetFiosType(const byte fiostype); truelight@0: truelight@0: typedef struct LandInfoData { truelight@0: Town *town; truelight@0: int32 costclear; truelight@0: AcceptedCargo ac; truelight@0: uint tile; truelight@0: TileDesc td; truelight@0: } LandInfoData; truelight@0: truelight@0: truelight@0: static void LandInfoWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: LandInfoData *lid; truelight@0: StringID str; truelight@0: uint32 *b; truelight@0: truelight@0: if (e->event == WE_PAINT) { truelight@0: DrawWindowWidgets(w); truelight@0: truelight@0: lid = WP(w,void_d).data; truelight@0: truelight@0: SET_DPARAM32(0, lid->td.dparam[0]); truelight@0: DrawStringCentered(140, 16, lid->td.str, 13); truelight@0: truelight@0: SET_DPARAM16(0, STR_01A6_N_A); truelight@0: if (lid->td.owner != OWNER_NONE && lid->td.owner != OWNER_WATER) truelight@0: GetNameOfOwner(lid->td.owner, lid->tile); truelight@0: DrawStringCentered(140, 27, STR_01A7_OWNER, 0); truelight@0: truelight@0: str = STR_01A4_COST_TO_CLEAR_N_A; truelight@0: if (lid->costclear != CMD_ERROR) { truelight@193: SET_DPARAM32(0, lid->costclear); truelight@0: str = STR_01A5_COST_TO_CLEAR; truelight@0: } truelight@0: DrawStringCentered(140, 38, str, 0); truelight@0: truelight@0: sprintf(_userstring, "%.4X", lid->tile); truelight@0: SET_DPARAM16(0, GET_TILE_X(lid->tile)); truelight@0: SET_DPARAM16(1, GET_TILE_Y(lid->tile)); truelight@0: SET_DPARAM16(2, STR_SPEC_USERSTRING); truelight@0: DrawStringCentered(140, 49, STR_LANDINFO_COORDS, 0); truelight@0: truelight@0: SET_DPARAM16(0, STR_01A9_NONE); truelight@0: if (lid->town != NULL) { truelight@0: SET_DPARAM16(0, lid->town->townnametype); truelight@0: SET_DPARAM32(1, lid->town->townnameparts); truelight@0: } truelight@0: DrawStringCentered(140,60, STR_01A8_LOCAL_AUTHORITY, 0); truelight@0: truelight@0: b = &GET_DPARAM(0); truelight@0: truelight@0: str = STR_01CE_CARGO_ACCEPTED - 1; truelight@0: truelight@0: if (lid->ac.amount_1 != 0) { truelight@0: if (lid->ac.amount_1 < 8) { truelight@0: SET_DPARAMX16(b, 0, STR_01D1_8); truelight@0: SET_DPARAMX8(b, 1, lid->ac.amount_1); truelight@0: b += 2; truelight@0: } truelight@0: SET_DPARAMX16(b, 0, _cargoc.names_s[lid->ac.type_1]); truelight@0: b++; truelight@0: str++; truelight@0: } truelight@0: truelight@0: if (lid->ac.amount_2 != 0) { truelight@0: if (lid->ac.amount_2 < 8) { truelight@0: SET_DPARAMX16(b, 0, STR_01D1_8); truelight@0: SET_DPARAMX8(b, 1, lid->ac.amount_2); truelight@0: b += 2; truelight@0: } truelight@0: SET_DPARAMX16(b, 0, _cargoc.names_s[lid->ac.type_2]); truelight@0: b++; truelight@0: str++; truelight@0: } truelight@0: truelight@0: if (lid->ac.amount_3 != 0) { truelight@0: if (lid->ac.amount_3 < 8) { truelight@0: SET_DPARAMX16(b, 0, STR_01D1_8); truelight@0: SET_DPARAMX8(b, 1, lid->ac.amount_3); truelight@0: b += 2; truelight@0: } truelight@0: SET_DPARAMX16(b, 0, _cargoc.names_s[lid->ac.type_3]); truelight@0: b++; truelight@0: str++; truelight@0: } truelight@0: truelight@0: if (str != (STR_01CE_CARGO_ACCEPTED - 1)) truelight@0: DrawStringMultiCenter(140, 76, str, 276); truelight@193: truelight@71: if (lid->td.build_date != 0) { truelight@71: SET_DPARAM16(0,lid->td.build_date); truelight@71: DrawStringCentered(140,71, STR_BUILD_DATE, 0); truelight@71: } truelight@0: } truelight@0: } truelight@0: truelight@0: static const Widget _land_info_widgets[] = { darkvater@176: { WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, truelight@0: { WWT_CAPTION, 14, 11, 279, 0, 13, STR_01A3_LAND_AREA_INFORMATION, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_IMGBTN, 14, 0, 279, 14, 92, 0x0, STR_NULL}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _land_info_desc = { truelight@0: -1, -1, 280, 93, truelight@0: WC_LAND_INFO,0, truelight@0: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, truelight@0: _land_info_widgets, truelight@0: LandInfoWndProc truelight@0: }; truelight@0: truelight@0: static void Place_LandInfo(uint tile) truelight@0: { truelight@0: Player *p; truelight@0: static LandInfoData lid; truelight@0: Window *w; truelight@0: int64 old_money; truelight@0: truelight@0: DeleteWindowById(WC_LAND_INFO, 0); truelight@0: truelight@0: w = AllocateWindowDesc(&_land_info_desc); truelight@0: WP(w,void_d).data = &lid; truelight@193: truelight@0: lid.tile = tile; truelight@0: lid.town = ClosestTownFromTile(tile, _patches.dist_local_authority); truelight@0: darkvater@3: if (_local_player >= MAX_PLAYERS) darkvater@3: p = DEREF_PLAYER(0); darkvater@3: else truelight@0: p = DEREF_PLAYER(_local_player); darkvater@3: darkvater@3: old_money = p->money64; darkvater@3: p->money64 = p->player_money = 0x7fffffff; darkvater@3: lid.costclear = DoCommandByTile(tile, 0, 0, 0, CMD_LANDSCAPE_CLEAR); darkvater@3: p->money64 = old_money; darkvater@3: UpdatePlayerMoney32(p); truelight@193: truelight@71: // Becuase build_date is not set yet in every TileDesc, we make sure it is empty truelight@71: lid.td.build_date = 0; truelight@193: truelight@0: GetAcceptedCargo(tile, &lid.ac); truelight@0: GetTileDesc(tile, &lid.td); truelight@193: darkvater@65: #if defined(_DEBUG) darkvater@65: DEBUG(misc, 0) ("TILE: %#x (%i,%i)", tile, GET_TILE_X(tile), GET_TILE_Y(tile)); darkvater@147: DEBUG(misc, 0) ("TILE: %d ", tile); darkvater@65: DEBUG(misc, 0) ("_map_type_and_height=%#x", _map_type_and_height[tile]); darkvater@65: DEBUG(misc, 0) ("_map2=%#x", _map2[tile]); darkvater@65: DEBUG(misc, 0) ("_map3_lo=%#x", _map3_lo[tile]); darkvater@65: DEBUG(misc, 0) ("_map3_hi=%#x", _map3_hi[tile]); darkvater@65: DEBUG(misc, 0) ("_map5=%#x", _map5[tile]); darkvater@65: DEBUG(misc, 0) ("_map_owner=%#x", _map_owner[tile]); darkvater@65: #endif truelight@0: } truelight@0: truelight@0: void PlaceLandBlockInfo() truelight@0: { truelight@0: if (_cursor.sprite == 0x2CF) { truelight@0: ResetObjectToPlace(); truelight@0: } else { truelight@0: _place_proc = Place_LandInfo; truelight@0: SetObjectToPlace(0x2CF, 1, 1, 0); truelight@0: } truelight@0: } truelight@0: truelight@0: truelight@0: static void AboutWindowProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: switch(e->event) { truelight@0: case WE_PAINT: { truelight@0: int x,y; truelight@0: DrawWindowWidgets(w); truelight@0: truelight@0: x = 200; truelight@0: y = 0; darkvater@74: DrawStringCentered(x, y += 17, STR_00B6_ORIGINAL_COPYRIGHT, 0); darkvater@74: DrawStringCentered(x, y += 10, STR_00B7_VERSION, 0); darkvater@74: DrawString(20, y += 20, STR_00B8_ORIGINAL_DESIGN_PROGRAM, 0); darkvater@74: DrawString(20, y += 10, STR_00B9_ORIGINAL_GRAPHICS, 0); darkvater@74: DrawString(20, y += 30, STR_SPECIAL_THANKS, 0); darkvater@74: // will probably be dynamic when stringhandling is finally reworked. darkvater@74: DrawString(20, y += 10, STR_SPECIAL_THANKS_SIGNALS, 0); darkvater@74: DrawString(20, y += 10, STR_SPECIAL_THANKS_CANALS, 0); darkvater@74: DrawString(20, y += 10, STR_SPECIAL_THANKS_FOUNDATIONS, 0); darkvater@74: DrawStringMultiCenter(x, w->height - 15, STR_00BA_COPYRIGHT_OPENTTD, 0x18E); truelight@0: break; truelight@0: } truelight@0: } truelight@0: } truelight@0: truelight@0: static const Widget _about_widgets[] = { darkvater@176: { WWT_CLOSEBOX, 14, 0, 10, 0, 13, STR_00C5, STR_NULL}, darkvater@176: { WWT_CAPTION, 14, 11, 399, 0, 13, STR_015B_OPENTTD, STR_NULL}, darkvater@176: { WWT_PANEL, 14, 0, 399, 14, 271, 0x0, STR_NULL}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _about_desc = { truelight@0: WDP_CENTER, WDP_CENTER, 400, 272, truelight@0: WC_GAME_OPTIONS,0, truelight@0: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, truelight@0: _about_widgets, truelight@0: AboutWindowProc truelight@0: }; truelight@0: truelight@0: truelight@0: void ShowAboutWindow() truelight@0: { truelight@0: DeleteWindowById(WC_GAME_OPTIONS, 0); truelight@0: AllocateWindowDesc(&_about_desc); truelight@0: } truelight@0: truelight@0: static int _tree_to_plant; truelight@0: truelight@0: static const byte _tree_base_by_landscape[4] = {0, 12, 20, 32}; truelight@0: static const byte _tree_count_by_landscape[4] = {12, 8, 12, 9}; truelight@0: static const uint32 _tree_sprites[] = { truelight@0: 0x655,0x663,0x678,0x62B,0x647,0x639,0x64E,0x632,0x67F,0x68D,0x69B,0x6A9, truelight@0: 0x6AF,0x6D2,0x6D9,0x6C4,0x6CB,0x6B6,0x6BD,0x6E0, truelight@0: 0x72E,0x734,0x74A,0x74F,0x76B,0x78F,0x788,0x77B,0x75F,0x774,0x720,0x797, truelight@0: 0x79E,0x30D87A5,0x30B87AC,0x7B3,0x7BA,0x30B87C1,0x30887C8,0x30A87CF,0x30B87D6 truelight@0: }; truelight@0: truelight@0: static void BuildTreesWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: switch(e->event) { truelight@0: case WE_PAINT: { truelight@0: int x,y; truelight@0: int i, count; truelight@0: truelight@0: DrawWindowWidgets(w); truelight@0: truelight@0: WP(w,tree_d).base = i = _tree_base_by_landscape[_opt.landscape]; truelight@0: WP(w,tree_d).count = count = _tree_count_by_landscape[_opt.landscape]; truelight@0: truelight@0: x = 18; truelight@0: y = 54; truelight@0: do { truelight@0: DrawSprite(_tree_sprites[i], x, y); truelight@0: x += 35; truelight@0: if (!(++i & 3)) { truelight@0: x -= 35*4; truelight@0: y += 47; truelight@0: } truelight@0: } while (--count); truelight@0: } break; truelight@0: truelight@0: case WE_CLICK: { truelight@0: int wid; truelight@0: truelight@0: switch(wid=e->click.widget) { truelight@0: case 0: truelight@0: ResetObjectToPlace(); truelight@0: return; truelight@0: case 3: case 4: case 5: case 6: truelight@0: case 7: case 8: case 9: case 10: truelight@0: case 11:case 12: case 13: case 14: truelight@0: if ( (uint)(wid-3) >= (uint)WP(w,tree_d).count) truelight@0: return; truelight@193: truelight@0: if (HandlePlacePushButton(w, wid, 0x7DA, 1, NULL)) truelight@0: _tree_to_plant = WP(w,tree_d).base + wid - 3; truelight@0: break; truelight@0: truelight@0: case 15: // tree of random type. truelight@0: if (HandlePlacePushButton(w, 15, 0x7DA, 1, NULL)) truelight@0: _tree_to_plant = -1; truelight@0: break; truelight@0: truelight@0: case 16: /* place trees randomly over the landscape*/ truelight@0: w->click_state |= 1 << 16; truelight@0: w->flags4 |= 5 << WF_TIMEOUT_SHL; truelight@0: SndPlayFx(0x13); truelight@0: PlaceTreesRandomly(); truelight@0: MarkWholeScreenDirty(); truelight@0: break; truelight@0: } truelight@0: } break; truelight@193: truelight@0: case WE_PLACE_OBJ: truelight@0: VpStartPlaceSizing(e->place.tile, VPM_X_AND_Y_LIMITED); truelight@0: VpSetPlaceSizingLimit(20); truelight@0: break; truelight@0: truelight@0: case WE_PLACE_DRAG: truelight@0: VpSelectTilesWithMethod(e->place.pt.x, e->place.pt.y, e->place.userdata); truelight@0: return; truelight@0: truelight@0: case WE_PLACE_MOUSEUP: truelight@0: if (e->click.pt.x != -1) { truelight@193: DoCommandP(e->place.tile, _tree_to_plant, e->place.starttile, NULL, truelight@0: CMD_PLANT_TREE | CMD_AUTO | CMD_MSG(STR_2805_CAN_T_PLANT_TREE_HERE)); truelight@0: } truelight@0: break; truelight@0: truelight@0: case WE_TIMEOUT: truelight@0: UnclickSomeWindowButtons(w, 1<<16); truelight@0: break; truelight@0: truelight@0: case WE_ABORT_PLACE_OBJ: truelight@0: w->click_state = 0; truelight@0: SetWindowDirty(w); truelight@0: break; truelight@0: } truelight@0: } truelight@0: truelight@0: static const Widget _build_trees_widgets[] = { truelight@0: { WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, truelight@0: { WWT_CAPTION, 7, 11, 142, 0, 13, STR_2802_TREES, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PANEL, 7, 0, 142, 14, 170, 0x0, STR_NULL}, truelight@0: { WWT_PANEL, 14, 2, 35, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 37, 70, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 72, 105, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 107, 140, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 2, 35, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 37, 70, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 72, 105, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 107, 140, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 2, 35, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 37, 70, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 72, 105, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 107, 140, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_CLOSEBOX, 14, 2, 140, 157, 168, STR_TREES_RANDOM_TYPE, STR_TREES_RANDOM_TYPE_TIP}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _build_trees_desc = { truelight@0: 497, 22, 143, 171, truelight@0: WC_BUILD_TOOLBAR,0, truelight@0: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, truelight@0: _build_trees_widgets, truelight@0: BuildTreesWndProc truelight@0: }; truelight@0: truelight@0: static const Widget _build_trees_scen_widgets[] = { truelight@0: { WWT_CLOSEBOX, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, truelight@0: { WWT_CAPTION, 7, 11, 142, 0, 13, STR_2802_TREES, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PANEL, 7, 0, 142, 14, 183, 0x0, STR_NULL}, truelight@0: { WWT_PANEL, 14, 2, 35, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 37, 70, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 72, 105, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 107, 140, 16, 61, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 2, 35, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 37, 70, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 72, 105, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 107, 140, 63, 108, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 2, 35, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 37, 70, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 72, 105, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, truelight@0: { WWT_PANEL, 14, 107, 140, 110, 155, 0x0, STR_280D_SELECT_TREE_TYPE_TO_PLANT}, darkvater@176: { WWT_CLOSEBOX, 14, 2, 140, 157, 168, STR_TREES_RANDOM_TYPE, STR_TREES_RANDOM_TYPE_TIP}, darkvater@176: { WWT_CLOSEBOX, 14, 2, 140, 170, 181, STR_028A_RANDOM_TREES, STR_028B_PLANT_TREES_RANDOMLY_OVER}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _build_trees_scen_desc = { truelight@0: -1, -1, 143, 184, truelight@0: WC_SCEN_BUILD_TREES,0, truelight@0: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, truelight@0: _build_trees_scen_widgets, truelight@0: BuildTreesWndProc truelight@0: }; truelight@0: truelight@193: truelight@0: void ShowBuildTreesToolbar() truelight@0: { truelight@0: DeleteWindowById(WC_BUILD_TOOLBAR, 0); truelight@0: AllocateWindowDesc(&_build_trees_desc); truelight@0: } truelight@0: truelight@0: void ShowBuildTreesScenToolbar() truelight@0: { truelight@0: AllocateWindowDescFront(&_build_trees_scen_desc, 0); truelight@0: } truelight@0: truelight@0: static uint32 _errmsg_decode_params[10]; truelight@0: static StringID _errmsg_message_1, _errmsg_message_2; truelight@0: static uint _errmsg_duration; truelight@0: truelight@0: truelight@0: static const Widget _errmsg_widgets[] = { darkvater@176: { WWT_CLOSEBOX, 4, 0, 10, 0, 13, STR_00C5, STR_NULL}, darkvater@176: { WWT_CAPTION, 4, 11, 239, 0, 13, STR_00B2_MESSAGE, STR_NULL}, darkvater@176: { WWT_PANEL, 4, 0, 239, 14, 45, 0x0, STR_NULL}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const Widget _errmsg_face_widgets[] = { darkvater@176: { WWT_CLOSEBOX, 4, 0, 10, 0, 13, STR_00C5, STR_NULL}, darkvater@176: { WWT_CAPTION, 4, 11, 333, 0, 13, STR_00B3_MESSAGE_FROM, STR_NULL}, darkvater@176: { WWT_PANEL, 4, 0, 333, 14, 136, 0x0, STR_NULL}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static void ErrmsgWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: switch(e->event) { truelight@0: case WE_PAINT: truelight@0: COPY_IN_DPARAM(0, _errmsg_decode_params, lengthof(_errmsg_decode_params)); truelight@0: DrawWindowWidgets(w); truelight@0: COPY_IN_DPARAM(0, _errmsg_decode_params, lengthof(_errmsg_decode_params)); truelight@0: if (w->widget != _errmsg_face_widgets) { truelight@0: DrawStringMultiCenter( truelight@0: 120, truelight@193: (_errmsg_message_1 == INVALID_STRING_ID ? 25 : 15), truelight@0: _errmsg_message_2, truelight@0: 238); truelight@0: if (_errmsg_message_1 != INVALID_STRING_ID) truelight@0: DrawStringMultiCenter( truelight@0: 120, truelight@0: 30, truelight@0: _errmsg_message_1, truelight@0: 238); truelight@0: } else { truelight@235: Player *p = DEREF_PLAYER(GET_DPARAMX8(_errmsg_decode_params,2)); truelight@0: DrawPlayerFace(p->face, p->player_color, 2, 16); truelight@0: truelight@0: DrawStringMultiCenter( truelight@0: 214, truelight@193: (_errmsg_message_1 == INVALID_STRING_ID ? 65 : 45), truelight@0: _errmsg_message_2, truelight@0: 238); truelight@0: if (_errmsg_message_1 != INVALID_STRING_ID) truelight@0: DrawStringMultiCenter( truelight@0: 214, truelight@0: 90, truelight@0: _errmsg_message_1, truelight@0: 238); truelight@0: } truelight@0: break; truelight@0: truelight@0: case WE_MOUSELOOP: truelight@0: if (_right_button_down) truelight@0: DeleteWindow(w); truelight@0: break; truelight@0: case WE_4: truelight@0: if (!--_errmsg_duration) truelight@0: DeleteWindow(w); truelight@0: break; truelight@0: case WE_DESTROY: { truelight@0: TileHighlightData *thd = _thd_ptr; truelight@0: TileIndex tile = thd->redsq; truelight@0: thd->redsq = 0; darkvater@172: _switch_mode_errorstr = INVALID_STRING_ID; truelight@0: if (tile != 0) truelight@0: MarkTileDirtyByTile(tile); truelight@0: break; truelight@0: } truelight@0: truelight@0: case WE_KEYPRESS: truelight@0: if (e->keypress.keycode == WKC_SPACE) { truelight@0: // Don't continue. truelight@0: e->keypress.cont = false; truelight@0: DeleteWindow(w); truelight@0: } truelight@0: break; truelight@0: } truelight@0: } truelight@0: truelight@0: void ShowErrorMessage(StringID msg_1, StringID msg_2, int x, int y) truelight@0: { truelight@0: Window *w; truelight@0: ViewPort *vp; truelight@0: Point pt; truelight@0: truelight@0: DeleteWindowById(WC_ERRMSG, 0); truelight@0: truelight@0: //assert(msg_2); truelight@0: if (msg_2 == 0) msg_2 = STR_EMPTY; truelight@0: truelight@0: _errmsg_message_1 = msg_1; truelight@0: _errmsg_message_2 = msg_2; truelight@0: COPY_OUT_DPARAM(_errmsg_decode_params, 0, lengthof(_errmsg_decode_params)); truelight@0: _errmsg_duration = _patches.errmsg_duration; truelight@0: if (!_errmsg_duration) truelight@0: return; truelight@193: truelight@0: if (_errmsg_message_1 != STR_013B_OWNED_BY || GET_DPARAMX8(_errmsg_decode_params,2) >= 8) { truelight@0: truelight@0: if ( (x|y) != 0) { truelight@0: pt = RemapCoords2(x, y); truelight@0: for(w=_windows; w->window_class != WC_MAIN_WINDOW; w++) {} truelight@0: vp = w->viewport; truelight@0: truelight@0: // move x pos to opposite corner truelight@0: pt.x = ((pt.x - vp->virtual_left) >> vp->zoom) + vp->left; truelight@0: pt.x = (pt.x < (_screen.width >> 1)) ? _screen.width - 260 : 20; truelight@193: truelight@0: // move y pos to opposite corner truelight@0: pt.y = ((pt.y - vp->virtual_top) >> vp->zoom) + vp->top; truelight@0: pt.y = (pt.y < (_screen.height >> 1)) ? _screen.height - 80 : 100; truelight@193: truelight@0: } else { truelight@0: pt.x = (_screen.width - 240) >> 1; truelight@0: pt.y = (_screen.height - 46) >> 1; truelight@0: } truelight@0: w = AllocateWindow(pt.x, pt.y, 240, 46, ErrmsgWndProc, WC_ERRMSG, _errmsg_widgets); truelight@0: } else { truelight@0: if ( (x|y) != 0) { truelight@0: pt = RemapCoords2(x, y); truelight@0: for(w=_windows; w->window_class != WC_MAIN_WINDOW; w++) {} truelight@0: vp = w->viewport; truelight@0: pt.x = clamp(((pt.x - vp->virtual_left) >> vp->zoom) + vp->left - (334/2), 0, _screen.width - 334); truelight@0: pt.y = clamp(((pt.y - vp->virtual_top) >> vp->zoom) + vp->top - (137/2), 22, _screen.height - 137); truelight@0: } else { truelight@0: pt.x = (_screen.width - 334) >> 1; truelight@0: pt.y = (_screen.height - 137) >> 1; truelight@0: } truelight@0: w = AllocateWindow(pt.x, pt.y, 334, 137, ErrmsgWndProc, WC_ERRMSG, _errmsg_face_widgets); truelight@0: } truelight@0: truelight@0: w->desc_flags = WDF_STD_BTN | WDF_DEF_WIDGET; truelight@0: } truelight@0: truelight@0: truelight@0: void ShowEstimatedCostOrIncome(int32 cost, int x, int y) truelight@0: { truelight@0: int msg = STR_0805_ESTIMATED_COST; truelight@0: truelight@0: if (cost < 0) { truelight@0: cost = -cost; truelight@0: msg = STR_0807_ESTIMATED_INCOME; truelight@0: } truelight@0: SET_DPARAM32(0, cost); truelight@0: ShowErrorMessage(-1, msg, x, y); truelight@0: } truelight@0: truelight@0: void ShowCostOrIncomeAnimation(int x, int y, int z, int32 cost) truelight@0: { truelight@0: int msg; truelight@0: Point pt = RemapCoords(x,y,z); truelight@0: truelight@0: msg = STR_0801_COST; truelight@0: if (cost < 0) { truelight@0: cost = -cost; truelight@0: msg = STR_0803_INCOME; truelight@0: } truelight@0: SET_DPARAM32(0, cost); truelight@0: AddTextEffect(msg, pt.x, pt.y, 0x250); truelight@0: } truelight@0: truelight@0: static Widget _tooltips_widgets[] = { darkvater@176: { WWT_PANEL, 14, 0, 199, 0, 31, 0x0, STR_NULL}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: truelight@0: static void TooltipsWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: truelight@0: switch(e->event) { truelight@0: case WE_PAINT: { truelight@193: GfxFillRect(0, 0, w->width - 1, w->height - 1, 0); truelight@0: GfxFillRect(1, 1, w->width - 2, w->height - 2, 0x44); truelight@0: DrawStringMultiCenter((w->width>>1), (w->height>>1)-5, WP(w,tooltips_d).string_id, 197); truelight@0: break; truelight@0: } truelight@0: case WE_MOUSELOOP: truelight@0: if (!_right_button_down) truelight@0: DeleteWindow(w); truelight@0: break; truelight@0: } truelight@0: } truelight@0: truelight@0: void GuiShowTooltips(StringID string_id) truelight@0: { truelight@0: Window *w; truelight@0: int right,bottom; truelight@0: int x,y; truelight@193: truelight@0: if (string_id == 0) truelight@0: return; truelight@0: truelight@0: w = FindWindowById(WC_TOOLTIPS, 0); truelight@0: if (w != NULL) { truelight@0: if (WP(w,tooltips_d).string_id == string_id) truelight@0: return; truelight@0: DeleteWindow(w); truelight@0: } truelight@0: truelight@0: GetString(str_buffr, string_id); truelight@0: assert(strlen(str_buffr) < sizeof(str_buffr) - 1); truelight@0: truelight@0: right = GetStringWidth(str_buffr) + 4; truelight@0: truelight@0: bottom = 14; truelight@0: if (right > 200) { truelight@0: bottom += ((right - 4) / 176) * 10; truelight@0: right = 200; truelight@0: } truelight@0: truelight@0: _tooltips_widgets[0].right = right; truelight@0: _tooltips_widgets[0].bottom = bottom; truelight@0: truelight@0: y = _cursor.pos.y + 30; truelight@0: if (y < 22) y = 22; truelight@0: truelight@0: if (y > (_screen.height - 44) && (y-=52) > (_screen.height - 44)) truelight@0: y = (_screen.height - 44); truelight@0: truelight@0: x = _cursor.pos.x - (right >> 1); truelight@0: if (x < 0) x = 0; truelight@0: if (x > (_screen.width - right)) x = _screen.width - right; truelight@0: truelight@0: w = AllocateWindow(x, y, right, bottom, TooltipsWndProc, WC_TOOLTIPS, _tooltips_widgets); truelight@0: WP(w,tooltips_d).string_id = string_id; truelight@0: w->flags4 &= ~WF_WHITE_BORDER_MASK; truelight@0: } truelight@0: truelight@0: truelight@0: static void DrawStationCoverageText(const uint *accepts, int str_x, int str_y, uint mask) truelight@0: { truelight@0: int i; truelight@0: byte *b; truelight@193: truelight@0: b = _userstring; truelight@0: b[0] = 0x81; truelight@0: b[1] = STR_000D_ACCEPTS; truelight@0: b[2] = STR_000D_ACCEPTS >> 8; truelight@0: b += 3; truelight@0: truelight@0: for(i=0; i!=NUM_CARGO; i++,mask>>=1) { truelight@0: if (accepts[i] >= 8 && (mask&1) ) { truelight@0: StringID id = _cargoc.names_s[i]; truelight@0: b[0] = 0x81; truelight@0: b[1] = (byte)(id & 255); truelight@0: b[2] = (byte)(id >> 8); truelight@0: b[3] = ','; truelight@0: b[4] = ' '; truelight@0: b += 5; truelight@0: } truelight@0: } truelight@0: truelight@0: if (b == (byte*)&_userstring[3]) { truelight@0: b[0] = 0x81; truelight@0: b[1] = STR_00D0_NOTHING; truelight@0: b[2] = STR_00D0_NOTHING >> 8; truelight@0: b[3] = 0; truelight@0: } else { truelight@0: b[-2] = 0; truelight@0: } truelight@0: truelight@0: DrawStringMultiLine(str_x, str_y, STR_SPEC_USERSTRING, 144); truelight@0: } truelight@0: truelight@0: void DrawStationCoverageAreaText(int sx, int sy, uint mask) { truelight@0: int x = _thd.pos.x; truelight@0: int y = _thd.pos.y; truelight@0: uint accepts[NUM_CARGO]; truelight@0: if (x != -1) { truelight@0: GetAcceptanceAroundTiles(accepts, TILE_FROM_XY(x,y), _thd.new_size.x >> 4, _thd.new_size.y >> 4); truelight@0: DrawStationCoverageText(accepts, sx, sy, mask); truelight@0: } truelight@0: } truelight@0: truelight@0: void CheckRedrawStationCoverage(Window *w) truelight@0: { truelight@0: if (_thd.dirty&1) { truelight@0: _thd.dirty&=~1; truelight@0: SetWindowDirty(w); truelight@0: } truelight@0: } truelight@0: truelight@0: truelight@0: void UnclickSomeWindowButtons(Window *w, uint32 mask) truelight@0: { truelight@0: uint32 x = w->click_state & mask; truelight@0: int i = 0; truelight@0: w->click_state ^= x; truelight@0: do { truelight@0: if (x&1) InvalidateWidget(w,i); truelight@0: } while(i++,x>>=1); truelight@0: } truelight@0: truelight@0: truelight@0: void UnclickWindowButtons(Window *w) truelight@0: { truelight@0: UnclickSomeWindowButtons(w, (uint32)-1); truelight@0: } truelight@0: truelight@0: truelight@0: void SetVScrollCount(Window *w, int num) truelight@0: { truelight@0: w->vscroll.count = num; truelight@0: num -= w->vscroll.cap; truelight@0: if (num < 0) num = 0; truelight@0: if (num < w->vscroll.pos) w->vscroll.pos = num; truelight@0: } truelight@0: truelight@0: void SetHScrollCount(Window *w, int num) truelight@0: { truelight@0: w->hscroll.count = num; truelight@0: num -= w->hscroll.cap; truelight@0: if (num < 0) num = 0; truelight@0: if (num < w->hscroll.pos) w->hscroll.pos = num; truelight@0: } truelight@0: truelight@0: truelight@0: int HandleEditBoxKey(Window *w, int wid, WindowEvent *we) truelight@0: { truelight@0: byte *p; truelight@0: int width,count; truelight@0: int key = we->keypress.ascii; truelight@0: truelight@0: we->keypress.cont = false; truelight@0: truelight@0: if (we->keypress.keycode == WKC_ESC) { truelight@0: return 2; truelight@0: } else if (we->keypress.keycode == WKC_RETURN) { truelight@0: return 1; truelight@0: } else { truelight@0: width = -1; truelight@0: p = WP(w,querystr_d).buf - 1; truelight@0: count = 0; truelight@0: do { truelight@0: if (*++p == 0) truelight@0: break; truelight@0: count++; truelight@0: width += _stringwidth_table[*p - 32]; truelight@0: } while (1); truelight@193: truelight@0: if (we->keypress.keycode == WKC_BACKSPACE) { truelight@0: if (count != 0) { truelight@0: WP(w,querystr_d).buf[count-1] = 0; truelight@0: InvalidateWidget(w, wid); truelight@0: } truelight@0: } else if (IS_INT_INSIDE((key = we->keypress.ascii), 32, 256)) { truelight@0: if (count < WP(w,querystr_d).maxlen && width + _stringwidth_table[key-32] <= WP(w,querystr_d).maxwidth) { truelight@0: WP(w,querystr_d).buf[count] = key; truelight@0: WP(w,querystr_d).buf[count+1] = 0; truelight@0: InvalidateWidget(w, wid); truelight@0: } truelight@0: } else { truelight@0: // key wasn't caught truelight@0: we->keypress.cont = true; truelight@0: } truelight@0: } truelight@0: truelight@0: return 0; truelight@0: } truelight@0: truelight@0: void HandleEditBox(Window *w, int wid) truelight@0: { truelight@0: bool b; truelight@0: truelight@0: /* caret changed? */ truelight@0: b = !!(_caret_timer & 0x20); truelight@0: if (b != WP(w,querystr_d).caret) { truelight@0: WP(w,querystr_d).caret = b; truelight@0: InvalidateWidget(w, wid); truelight@0: } truelight@0: } truelight@0: truelight@0: void DrawEditBox(Window *w, int wid) truelight@0: { truelight@0: const Widget *wi = w->widget + wid; truelight@0: int x; truelight@0: truelight@0: GfxFillRect(wi->left+1, wi->top+1, wi->right-1, wi->bottom-1, 215); truelight@0: x = DoDrawString(WP(w,querystr_d).buf, wi->left+2, wi->top+1, 8); truelight@0: if (WP(w,querystr_d).caret) truelight@0: DoDrawString("_", x, wi->top+1, 12); truelight@0: } truelight@0: truelight@0: truelight@0: #define MAX_QUERYSTR_LEN 64 truelight@0: truelight@0: static void QueryStringWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: switch(e->event) { truelight@0: case WE_PAINT: { truelight@0: // int x; truelight@0: truelight@0: SET_DPARAM16(0, WP(w,querystr_d).caption); truelight@0: DrawWindowWidgets(w); truelight@0: truelight@0: DrawEditBox(w, 5); truelight@0: } break; truelight@0: truelight@0: case WE_CLICK: truelight@0: switch(e->click.widget) { truelight@0: case 3: DeleteWindow(w); break; truelight@0: case 4: truelight@0: press_ok:; truelight@0: if (str_eq(WP(w,querystr_d).buf, WP(w,querystr_d).buf + MAX_QUERYSTR_LEN)) { truelight@0: DeleteWindow(w); truelight@0: } else { truelight@0: byte *buf = WP(w,querystr_d).buf; tron@390: WindowClass wnd_class = WP(w,querystr_d).wnd_class; tron@390: WindowNumber wnd_num = WP(w,querystr_d).wnd_num; tron@390: Window *parent; tron@390: truelight@0: DeleteWindow(w); tron@390: parent = FindWindowById(wnd_class, wnd_num); truelight@0: if (parent != NULL) { truelight@0: WindowEvent e; truelight@0: e.event = WE_ON_EDIT_TEXT; truelight@0: e.edittext.str = buf; truelight@0: parent->wndproc(parent, &e); truelight@0: } truelight@0: } truelight@0: break; truelight@0: } truelight@0: break; truelight@0: truelight@0: case WE_MOUSELOOP: { truelight@0: if (!FindWindowById(WP(w,querystr_d).wnd_class, WP(w,querystr_d).wnd_num)) { truelight@0: DeleteWindow(w); truelight@0: return; truelight@0: } truelight@0: HandleEditBox(w, 5); truelight@0: } break; truelight@0: truelight@0: case WE_KEYPRESS: { truelight@0: switch(HandleEditBoxKey(w, 5, e)) { truelight@0: case 1: // Return truelight@0: goto press_ok; truelight@0: case 2: // Escape truelight@0: DeleteWindow(w); truelight@0: break; truelight@0: } truelight@0: } break; truelight@0: truelight@0: case WE_DESTROY: truelight@0: _query_string_active = false; truelight@0: break; truelight@0: } truelight@0: } truelight@0: truelight@0: static const Widget _query_string_widgets[] = { darkvater@176: { WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_NULL}, darkvater@176: { WWT_CAPTION, 14, 11, 259, 0, 13, STR_012D, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 0, 259, 14, 29, 0x0, STR_NULL}, darkvater@176: { WWT_TEXTBTN, 14, 0, 129, 30, 41, STR_012E_CANCEL, STR_NULL}, darkvater@176: { WWT_TEXTBTN, 14, 130, 259, 30, 41, STR_012F_OK, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 2, 257, 16, 27, 0x0, STR_NULL}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _query_string_desc = { truelight@0: 190, 219, 260, 42, truelight@0: WC_QUERY_STRING,0, truelight@0: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET, truelight@0: _query_string_widgets, truelight@0: QueryStringWndProc truelight@0: }; truelight@0: truelight@0: static byte _edit_str_buf[MAX_QUERYSTR_LEN*2]; truelight@0: truelight@0: void ShowQueryString(StringID str, StringID caption, int maxlen, int maxwidth, byte window_class, uint16 window_number) truelight@0: { truelight@0: Window *w; truelight@0: truelight@0: #define _orig_edit_str_buf (_edit_str_buf+MAX_QUERYSTR_LEN) truelight@0: truelight@0: DeleteWindowById(WC_QUERY_STRING, 0); truelight@0: DeleteWindowById(WC_SAVELOAD, 0); truelight@0: truelight@0: if (str == 0xFFFF) { truelight@0: memcpy(_orig_edit_str_buf, str_buffr, MAX_QUERYSTR_LEN); truelight@0: } else { truelight@0: GetString(_orig_edit_str_buf, str); truelight@0: } truelight@0: _orig_edit_str_buf[maxlen] = 0; truelight@0: truelight@0: memcpy(_edit_str_buf, _orig_edit_str_buf, MAX_QUERYSTR_LEN); truelight@0: truelight@0: w = AllocateWindowDesc(&_query_string_desc); truelight@0: truelight@0: w->click_state = 1 << 5; truelight@0: WP(w,querystr_d).caption = caption; truelight@0: WP(w,querystr_d).wnd_class = window_class; truelight@0: WP(w,querystr_d).wnd_num = window_number; truelight@0: WP(w,querystr_d).caret = 0; truelight@0: WP(w,querystr_d).maxlen = maxlen; truelight@0: WP(w,querystr_d).maxwidth = maxwidth; truelight@0: WP(w,querystr_d).buf = _edit_str_buf; truelight@0: truelight@0: _query_string_active = true; truelight@0: } truelight@0: truelight@0: static const Widget _load_dialog_1_widgets[] = { darkvater@176: { WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, darkvater@176: { WWT_CAPTION, 14, 11, 256, 0, 13, STR_4001_LOAD_GAME, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PUSHTXTBTN, 14, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_TIP}, darkvater@176: { WWT_PUSHTXTBTN, 14, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_TIP}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 26, 47, 0x0, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 48, 293, 0x0, STR_NULL}, darkvater@176: { WWT_6, 14, 2, 243, 50, 291, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES}, darkvater@176: { WWT_SCROLLBAR, 14, 246, 256, 48, 293, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const Widget _load_dialog_2_widgets[] = { darkvater@176: { WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, darkvater@176: { WWT_CAPTION, 14, 11, 256, 0, 13, STR_0298_LOAD_SCENARIO, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PUSHTXTBTN, 14, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_TIP}, darkvater@176: { WWT_PUSHTXTBTN, 14, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_TIP}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 26, 47, 0x0, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 48, 293, 0x0, STR_NULL}, darkvater@176: { WWT_6, 14, 2, 243, 50, 291, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES}, darkvater@176: { WWT_SCROLLBAR, 14, 246, 256, 48, 293, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const Widget _save_dialog_widgets[] = { darkvater@176: { WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, darkvater@176: { WWT_CAPTION, 14, 11, 256, 0, 13, STR_4000_SAVE_GAME, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PUSHTXTBTN, 14, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_TIP}, darkvater@176: { WWT_PUSHTXTBTN, 14, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_TIP}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 26, 47, 0x0, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 48, 291, 0x0, STR_NULL}, darkvater@176: { WWT_6, 14, 2, 243, 50, 289, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES}, darkvater@176: { WWT_SCROLLBAR, 14, 246, 256, 48, 291, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 292, 307, 0x0, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 2, 254, 294, 305, 0x0, STR_400B_CURRENTLY_SELECTED_NAME}, darkvater@176: { WWT_PUSHTXTBTN, 14, 0, 127, 308, 319, STR_4003_DELETE, STR_400C_DELETE_THE_CURRENTLY_SELECTED}, darkvater@176: { WWT_PUSHTXTBTN, 14, 128, 256, 308, 319, STR_4002_SAVE, STR_400D_SAVE_THE_CURRENT_GAME_USING}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static const Widget _save_dialog_scen_widgets[] = { darkvater@176: { WWT_TEXTBTN, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, truelight@0: { WWT_CAPTION, 14, 11, 256, 0, 13, STR_0299_SAVE_SCENARIO, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PUSHTXTBTN, 14, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_TIP}, darkvater@176: { WWT_PUSHTXTBTN, 14, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_TIP}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 26, 47, 0x0, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 48, 291, 0x0, STR_NULL}, darkvater@176: { WWT_6, 14, 2, 243, 50, 289, 0x0, STR_400A_LIST_OF_DRIVES_DIRECTORIES}, darkvater@176: { WWT_SCROLLBAR, 14, 246, 256, 48, 291, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, darkvater@176: { WWT_IMGBTN, 14, 0, 256, 292, 307, 0x0, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 2, 254, 294, 305, 0x0, STR_400B_CURRENTLY_SELECTED_NAME}, darkvater@176: { WWT_PUSHTXTBTN, 14, 0, 127, 308, 319, STR_4003_DELETE, STR_400C_DELETE_THE_CURRENTLY_SELECTED}, darkvater@176: { WWT_PUSHTXTBTN, 14, 128, 256, 308, 319, STR_4002_SAVE, STR_400D_SAVE_THE_CURRENT_GAME_USING}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: truelight@0: static FiosItem *_fios_list; truelight@0: static int _fios_num; truelight@0: static int _saveload_mode; truelight@0: truelight@0: static void BuildFileList() truelight@0: { truelight@0: FiosFreeSavegameList(); truelight@0: if(_saveload_mode==SLD_NEW_GAME || _saveload_mode==SLD_LOAD_SCENARIO || _saveload_mode==SLD_SAVE_SCENARIO) truelight@0: _fios_list = FiosGetScenarioList(&_fios_num, _saveload_mode); truelight@0: else truelight@0: _fios_list = FiosGetSavegameList(&_fios_num, _saveload_mode); truelight@0: } truelight@0: truelight@0: static void DrawFiosTexts() truelight@0: { darkvater@222: const char *path; truelight@0: StringID str; truelight@0: truelight@0: str = FiosGetDescText(&path); truelight@0: if (str != 0) truelight@0: DrawString(2, 37, str, 0); truelight@0: DoDrawString(path, 2, 27, 16); truelight@0: } truelight@0: truelight@0: /* FIOS_TYPE_FILE, FIOS_TYPE_OLDFILE etc. different colours */ truelight@0: static const byte _fios_colors[] = {13, 9, 9, 6, 5, 6, 5}; truelight@0: truelight@0: #if defined(_WIN32) truelight@0: extern int CDECL compare_FiosItems (const void *a, const void *b); truelight@0: #else truelight@0: extern int compare_FiosItems (const void *a, const void *b); truelight@0: #endif truelight@0: truelight@0: truelight@0: static void MakeSortedSaveGameList() truelight@0: { truelight@0: /* Directories are always above the files (FIOS_TYPE_DIR) truelight@0: * Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE) truelight@0: * Only sort savegames/scenarios, not directories truelight@0: */ truelight@0: truelight@0: int i, sort_start, sort_end, s_amount; truelight@0: i = sort_start = sort_end = 0; truelight@0: truelight@0: while (i < _fios_num) { truelight@0: if (_fios_list[i].type == FIOS_TYPE_DIR || _fios_list[i].type == FIOS_TYPE_PARENT) truelight@0: sort_start++; truelight@0: truelight@0: if (_fios_list[i].type == FIOS_TYPE_DRIVE) truelight@0: sort_end++; truelight@0: truelight@0: i++; truelight@0: } truelight@0: truelight@0: s_amount = _fios_num - sort_start - sort_end; truelight@0: if ((bool)s_amount) truelight@0: qsort(_fios_list + sort_start, s_amount, sizeof(FiosItem), compare_FiosItems); truelight@0: } truelight@0: tron@402: static void GenerateFileName(void) tron@402: { tron@402: const Player *p = DEREF_PLAYER(_local_player); tron@402: SET_DPARAM16(0, p->name_1); tron@402: SET_DPARAM32(1, p->name_2); tron@402: SET_DPARAM16(2, _date); tron@402: GetString(_edit_str_buf, STR_4004); tron@402: } tron@402: truelight@0: static void SaveLoadDlgWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: const int list_start = 51; truelight@0: truelight@0: switch(e->event) { truelight@0: case WE_PAINT: { truelight@0: int y,pos; truelight@0: const FiosItem *item; truelight@0: truelight@0: SetVScrollCount(w, _fios_num); truelight@0: DrawWindowWidgets(w); truelight@0: DrawFiosTexts(); truelight@0: truelight@0: if (_savegame_sort_dirty) { truelight@0: _savegame_sort_dirty = false; truelight@0: MakeSortedSaveGameList(); truelight@0: } truelight@0: truelight@0: GfxFillRect(3, list_start, 3+239, list_start+239, 0xD7); truelight@0: DoDrawString(_savegame_sort_order & 1 ? "\xAA" : "\xA0", _savegame_sort_order <= 1 ? 248 : 118, 15, 0x10); truelight@0: truelight@0: y = list_start; truelight@0: pos = w->vscroll.pos; truelight@0: while (pos < _fios_num) { truelight@0: item = _fios_list + pos; truelight@0: DoDrawString(item->title[0] ? item->title : item->name, 4, y, _fios_colors[item->type] ); truelight@0: pos++; truelight@0: y+=10; truelight@0: if (y >= w->vscroll.cap*10+list_start) truelight@0: break; truelight@0: } truelight@0: truelight@0: if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) { truelight@0: DrawEditBox(w, 9); truelight@0: } truelight@0: break; truelight@0: } truelight@0: case WE_CLICK: truelight@0: switch(e->click.widget) { truelight@0: case 2: /* Sort save names by name */ truelight@0: _savegame_sort_order = (_savegame_sort_order == 2) ? 3 : 2; truelight@0: _savegame_sort_dirty = true; truelight@0: SetWindowDirty(w); truelight@0: break; truelight@0: truelight@0: case 3: /* Sort save names by date */ truelight@0: _savegame_sort_order = (_savegame_sort_order == 0) ? 1 : 0; truelight@0: _savegame_sort_dirty = true; truelight@0: SetWindowDirty(w); truelight@0: break; truelight@0: truelight@0: case 6: { /* Click the listbox */ truelight@0: int y = (e->click.pt.y - list_start) / 10; truelight@0: char *name; truelight@0: const FiosItem *file; truelight@0: truelight@0: if (y < 0 || (y += w->vscroll.pos) >= w->vscroll.count) truelight@0: return; truelight@0: truelight@0: file = _fios_list + y; truelight@193: truelight@0: if ((name = FiosBrowseTo(file)) != NULL) { truelight@0: if (_saveload_mode == SLD_LOAD_GAME) { truelight@0: _switch_mode = SM_LOAD; truelight@0: SetFiosType(file->type); truelight@0: strcpy(_file_to_saveload.name, name); truelight@0: DeleteWindow(w); truelight@0: } else if (_saveload_mode == SLD_LOAD_SCENARIO) { truelight@0: _switch_mode = SM_LOAD_SCENARIO; truelight@0: SetFiosType(file->type); truelight@0: strcpy(_file_to_saveload.name, name); truelight@0: DeleteWindow(w); truelight@0: } else { truelight@0: // SLD_SAVE_GAME, SLD_SAVE_SCENARIO copy clicked name to editbox truelight@0: strcpy(WP(w,querystr_d).buf, file->title[0] ? file->title : file->name); truelight@0: InvalidateWidget(w, 9); truelight@0: } truelight@0: } else { truelight@0: // Changed directory, need repaint. truelight@0: SetWindowDirty(w); truelight@0: BuildFileList(); truelight@0: } truelight@0: break; truelight@0: } truelight@0: case 10: case 11: /* Delete, Save game */ truelight@0: break; truelight@0: } truelight@0: break; truelight@0: case WE_MOUSELOOP: truelight@0: HandleEditBox(w, 9); truelight@0: break; truelight@0: case WE_KEYPRESS: truelight@0: switch (HandleEditBoxKey(w, 9, e)) { truelight@0: case 1: truelight@0: HandleButtonClick(w, 11); truelight@0: break; truelight@0: } truelight@0: break; truelight@0: case WE_TIMEOUT: truelight@0: if (HASBIT(w->click_state, 10)) { /* Delete button clicked */ truelight@0: FiosDelete(WP(w,querystr_d).buf); truelight@0: SetWindowDirty(w); truelight@0: BuildFileList(); tron@402: if (_saveload_mode == SLD_SAVE_GAME) tron@402: GenerateFileName(); /* Reset file name to current date */ truelight@0: } else if (HASBIT(w->click_state, 11)) { /* Save button clicked */ truelight@0: _switch_mode = SM_SAVE; truelight@0: FiosMakeSavegameName(_file_to_saveload.name, WP(w,querystr_d).buf); truelight@0: } truelight@0: break; truelight@0: case WE_DESTROY: dominik@278: // pause is only used in single-player, non-editor mode dominik@278: if(!_networking && (_game_mode != GM_EDITOR)) dominik@278: DoCommandP(0, 0, 0, NULL, CMD_PAUSE); truelight@0: _query_string_active = false; truelight@0: FiosFreeSavegameList(); truelight@0: break; truelight@193: } truelight@0: } truelight@0: truelight@0: static const WindowDesc _load_dialog_desc = { truelight@0: WDP_CENTER, WDP_CENTER, 257, 294, truelight@0: WC_SAVELOAD,0, truelight@0: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS, truelight@0: _load_dialog_1_widgets, truelight@0: SaveLoadDlgWndProc, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _load_dialog_scen_desc = { truelight@0: WDP_CENTER, WDP_CENTER, 257, 294, truelight@0: WC_SAVELOAD,0, truelight@0: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS, truelight@0: _load_dialog_2_widgets, truelight@0: SaveLoadDlgWndProc, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _save_dialog_desc = { truelight@0: WDP_CENTER, WDP_CENTER, 257, 320, truelight@0: WC_SAVELOAD,0, truelight@0: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS, truelight@0: _save_dialog_widgets, truelight@0: SaveLoadDlgWndProc, truelight@0: }; truelight@0: truelight@0: static const WindowDesc _save_dialog_scen_desc = { truelight@0: WDP_CENTER, WDP_CENTER, 257, 320, truelight@0: WC_SAVELOAD,0, truelight@0: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS, truelight@0: _save_dialog_scen_widgets, truelight@0: SaveLoadDlgWndProc, truelight@0: }; truelight@0: truelight@0: static const WindowDesc * const _saveload_dialogs[] = { truelight@0: &_load_dialog_desc, truelight@0: &_load_dialog_scen_desc, truelight@0: &_save_dialog_desc, truelight@0: &_save_dialog_scen_desc, truelight@0: }; truelight@0: truelight@0: void ShowSaveLoadDialog(int mode) truelight@0: { truelight@0: Window *w; truelight@0: truelight@0: SetObjectToPlace(1, 0, 0, 0); truelight@0: DeleteWindowById(WC_QUERY_STRING, 0); truelight@0: DeleteWindowById(WC_SAVELOAD, 0); truelight@0: truelight@0: _saveload_mode = mode; truelight@0: truelight@0: w = AllocateWindowDesc(_saveload_dialogs[mode]); truelight@0: w->vscroll.cap = 24; truelight@0: w->click_state |= (1 << 6); truelight@0: WP(w,querystr_d).caret = 0; truelight@0: WP(w,querystr_d).maxlen = MAX_QUERYSTR_LEN; truelight@0: WP(w,querystr_d).maxwidth = 240; truelight@0: WP(w,querystr_d).buf = _edit_str_buf; truelight@0: truelight@0: if (mode == SLD_SAVE_GAME) { tron@402: GenerateFileName(); truelight@0: } else if (mode == SLD_SAVE_SCENARIO) { truelight@0: strcpy(_edit_str_buf, "UNNAMED"); truelight@0: } truelight@0: dominik@278: // pause is only used in single-player, non-editor mode dominik@278: if(_game_mode != GM_MENU && !_networking && (_game_mode != GM_EDITOR)) dominik@278: DoCommandP(0, 1, 0, NULL, CMD_PAUSE); dominik@278: truelight@0: BuildFileList(); truelight@0: truelight@0: ResetObjectToPlace(); truelight@0: } truelight@0: truelight@0: void RedrawAutosave() truelight@0: { truelight@0: SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0)); truelight@0: } truelight@0: truelight@0: static const Widget _select_scenario_widgets[] = { darkvater@176: { WWT_TEXTBTN, 7, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, truelight@0: { WWT_CAPTION, 7, 11, 256, 0, 13, STR_400E_SELECT_NEW_GAME_TYPE, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PUSHTXTBTN, 7, 0, 127, 14, 25, STR_SORT_BY_NAME, STR_SORT_TIP}, darkvater@176: { WWT_PUSHTXTBTN, 7, 128, 256, 14, 25, STR_SORT_BY_DATE, STR_SORT_TIP}, darkvater@176: { WWT_IMGBTN, 7, 0, 245, 26, 319, 0x0, STR_NULL}, darkvater@176: { WWT_6, 7, 2, 243, 28, 317, 0x0, STR_400F_SELECT_SCENARIO_GREEN_PRE}, darkvater@176: { WWT_SCROLLBAR, 7, 246, 256, 26, 319, 0x0, STR_0190_SCROLL_BAR_SCROLLS_LIST}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: static void SelectScenarioWndProc(Window *w, WindowEvent *e) { truelight@0: const int list_start = 45; truelight@0: switch(e->event) { truelight@0: case WE_PAINT: truelight@0: { truelight@0: int y,pos; truelight@0: const FiosItem *item; truelight@0: truelight@0: if (_savegame_sort_dirty) { truelight@0: _savegame_sort_dirty = false; truelight@0: MakeSortedSaveGameList(); truelight@0: } truelight@193: truelight@0: SetVScrollCount(w, _fios_num); truelight@0: truelight@0: DrawWindowWidgets(w); truelight@0: DoDrawString(_savegame_sort_order & 1 ? "\xAA" : "\xA0", _savegame_sort_order <= 1 ? 248 : 118, 15, 0x10); truelight@0: DrawString(4, 32, STR_4010_GENERATE_RANDOM_NEW_GAME, 9); truelight@0: truelight@0: y = list_start; truelight@0: pos = w->vscroll.pos; truelight@0: while (pos < _fios_num) { truelight@0: item = _fios_list + pos; truelight@0: DoDrawString(item->title[0] ? item->title : item->name, 4, y, _fios_colors[item->type] ); truelight@0: pos++; truelight@0: y+=10; truelight@0: if (y >= w->vscroll.cap*10+list_start) truelight@0: break; truelight@0: } truelight@0: } truelight@0: break; truelight@0: truelight@0: case WE_CLICK: truelight@0: switch(e->click.widget) { truelight@0: case 2: /* Sort scenario names by name */ truelight@0: _savegame_sort_order = (_savegame_sort_order == 2) ? 3 : 2; truelight@0: _savegame_sort_dirty = true; truelight@0: SetWindowDirty(w); truelight@0: break; truelight@0: truelight@0: case 3: /* Sort scenario names by date */ truelight@0: _savegame_sort_order = (_savegame_sort_order == 0) ? 1 : 0; truelight@0: _savegame_sort_dirty = true; truelight@0: SetWindowDirty(w); truelight@0: break; truelight@0: truelight@0: case 5: /* Click the listbox */ truelight@0: if(e->click.pt.y < list_start) truelight@0: DoCommandP(0, Random(), InteractiveRandom(), NULL, CMD_GEN_RANDOM_NEW_GAME); truelight@0: else { truelight@0: char *name; truelight@0: int y = (e->click.pt.y - list_start) / 10; truelight@0: const FiosItem *file; truelight@0: truelight@0: if (y < 0 || (y += w->vscroll.pos) >= w->vscroll.count) truelight@0: return; truelight@0: truelight@0: file = _fios_list + y; truelight@193: truelight@0: if ((name = FiosBrowseTo(file)) != NULL) { truelight@0: SetFiosType(file->type); truelight@0: strcpy(_file_to_saveload.name, name); truelight@0: DeleteWindow(w); truelight@0: DoCommandP(0, Random(), InteractiveRandom(), NULL, CMD_START_SCENARIO); truelight@0: } truelight@0: } truelight@0: break; truelight@0: } truelight@0: case WE_DESTROY: truelight@0: break; truelight@0: } truelight@0: } truelight@0: truelight@0: static void SetFiosType(const byte fiostype) truelight@0: { truelight@0: switch (fiostype) { truelight@0: case FIOS_TYPE_FILE: case FIOS_TYPE_SCENARIO: truelight@0: _file_to_saveload.mode = SL_LOAD; truelight@0: break; truelight@0: case FIOS_TYPE_OLDFILE: case FIOS_TYPE_OLD_SCENARIO: truelight@0: _file_to_saveload.mode = SL_OLD_LOAD; truelight@0: break; truelight@0: default: truelight@0: _file_to_saveload.mode = SL_INVALID; truelight@0: } truelight@0: } truelight@0: truelight@0: static const WindowDesc _select_scenario_desc = { truelight@0: WDP_CENTER, WDP_CENTER, 257, 320, truelight@0: WC_SAVELOAD,0, truelight@0: WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS, truelight@0: _select_scenario_widgets, truelight@0: SelectScenarioWndProc truelight@0: }; truelight@0: truelight@0: void AskForNewGameToStart() truelight@0: { truelight@0: Window *w; truelight@0: truelight@0: DeleteWindowById(WC_QUERY_STRING, 0); truelight@0: DeleteWindowById(WC_SAVELOAD, 0); truelight@0: truelight@0: _saveload_mode = SLD_NEW_GAME; truelight@0: BuildFileList(); truelight@0: truelight@0: w = AllocateWindowDesc(&_select_scenario_desc); truelight@0: w->vscroll.cap = 27; truelight@0: } truelight@0: tron@410: static int32 ClickMoneyCheat(int32 p1, int32 p2) truelight@0: { truelight@0: DoCommandP(0, -10000000, 0, NULL, CMD_MONEY_CHEAT); truelight@0: return true; truelight@0: } truelight@0: truelight@0: // p1 player to set to, p2 is -1 or +1 (down/up) tron@410: static int32 ClickChangePlayerCheat(int32 p1, int32 p2) truelight@0: { darkvater@155: while(p1 >= 0 && p1 < MAX_PLAYERS) { darkvater@155: if (_players[p1].is_active) { truelight@0: _local_player = p1; dominik@138: MarkWholeScreenDirty(); truelight@0: return _local_player; truelight@0: } truelight@0: p1 += p2; truelight@0: } darkvater@155: darkvater@155: return _local_player; truelight@0: } truelight@0: dominik@100: // p1 -1 or +1 (down/up) dominik@100: int32 ClickChangeClimateCheat(int32 p1, int32 p2) dominik@100: { dominik@104: if(p1==-1) p1 = 3; dominik@104: if(p1==4) p1 = 0; dominik@100: _opt.landscape = p1; dominik@100: GfxLoadSprites(); dominik@100: MarkWholeScreenDirty(); dominik@100: return _opt.landscape; dominik@100: } dominik@100: dominik@108: extern void EnginesMonthlyLoop(); dominik@108: dominik@108: // p2 1 (increase) or -1 (decrease) dominik@108: int32 ClickChangeDateCheat(int32 p1, int32 p2) dominik@108: { dominik@108: YearMonthDay ymd; dominik@108: ConvertDayToYMD(&ymd, _date); dominik@108: dominik@108: if((ymd.year==0 && p2==-1) || (ymd.year==170 && p2==1)) return _cur_year; dominik@108: dominik@108: SetDate(ConvertYMDToDay(_cur_year + p2, ymd.month, ymd.day)); dominik@108: EnginesMonthlyLoop(); dominik@108: SetWindowDirty(FindWindowById(WC_STATUS_BAR, 0)); dominik@108: return _cur_year; dominik@108: } dominik@100: truelight@0: typedef int32 CheckButtonClick(int32, int32); truelight@0: truelight@0: typedef struct CheatEntry { truelight@0: byte type; // type of selector truelight@0: byte flags; // selector flags truelight@0: StringID str; // string with descriptive text truelight@0: void *variable; // pointer to the variable truelight@0: bool *been_used; // has this cheat been used before? truelight@0: CheckButtonClick *click_proc; // procedure truelight@0: int16 min,max; // range for spinbox setting truelight@0: uint16 step; // step for spinbox truelight@0: } CheatEntry; truelight@0: truelight@0: enum { truelight@0: CE_BOOL = 0, truelight@0: CE_UINT8 = 1, truelight@0: CE_INT16 = 2, truelight@0: CE_UINT16 = 3, truelight@0: CE_INT32 = 4, truelight@0: CE_BYTE = 5, truelight@0: CE_CLICK = 6, truelight@0: truelight@0: CF_0ISDIS = 1, truelight@0: CF_NOCOMMA = 2, truelight@0: }; truelight@0: truelight@0: static int32 ReadCE(const CheatEntry*ce) truelight@0: { truelight@0: switch(ce->type) { truelight@0: case CE_BOOL: return *(bool*)ce->variable; truelight@0: case CE_UINT8: return *(uint8*)ce->variable; truelight@0: case CE_INT16: return *(int16*)ce->variable; truelight@0: case CE_UINT16: return *(uint16*)ce->variable; truelight@0: case CE_INT32: return *(int32*)ce->variable; truelight@0: case CE_BYTE: return *(byte*)ce->variable; truelight@0: case CE_CLICK: return 0; truelight@0: default: truelight@0: NOT_REACHED(); truelight@0: } truelight@193: truelight@0: /* useless, but avoids compiler warning this way */ truelight@0: return 0; truelight@0: } truelight@0: truelight@0: static void WriteCE(const CheatEntry *ce, int32 val) truelight@0: { truelight@0: switch(ce->type) { truelight@0: case CE_BOOL: *(bool*)ce->variable = (bool)val; break; truelight@0: case CE_BYTE: *(byte*)ce->variable = (byte)val; break; truelight@0: case CE_UINT8: *(uint8*)ce->variable = (uint8)val; break; truelight@0: case CE_INT16: *(int16*)ce->variable = (int16)val; break; truelight@0: case CE_UINT16: *(uint16*)ce->variable = (uint16)val; break; truelight@0: case CE_INT32: *(int32*)ce->variable = val; break; truelight@0: case CE_CLICK: break; truelight@0: default: truelight@0: NOT_REACHED(); truelight@0: } truelight@0: } truelight@0: truelight@0: truelight@0: static const CheatEntry _cheats_ui[] = { darkvater@179: {CE_CLICK, 0, STR_CHEAT_MONEY, &_cheats.money.value, &_cheats.money.been_used, &ClickMoneyCheat, 0, 0, 0}, darkvater@179: {CE_UINT8, 0, STR_CHEAT_CHANGE_PLAYER, &_local_player, &_cheats.switch_player.been_used, &ClickChangePlayerCheat, 0, 11, 1}, darkvater@179: {CE_BOOL, 0, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, NULL, 0, 0, 0}, darkvater@179: {CE_BOOL, 0, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value,&_cheats.crossing_tunnels.been_used,NULL, 0, 0, 0}, darkvater@179: {CE_BOOL, 0, STR_CHEAT_BUILD_IN_PAUSE, &_cheats.build_in_pause.value, &_cheats.build_in_pause.been_used, NULL, 0, 0, 0}, darkvater@179: {CE_BOOL, 0, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, NULL, 0, 0, 0}, darkvater@179: {CE_UINT8, 0, STR_CHEAT_SWITCH_CLIMATE, &_opt.landscape, &_cheats.switch_climate.been_used, &ClickChangeClimateCheat,-1, 4, 1}, darkvater@179: {CE_UINT8, 0, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat, -1, 1, 1}, truelight@0: }; truelight@0: truelight@0: truelight@0: static const Widget _cheat_widgets[] = { darkvater@176: { WWT_CLOSEBOX, 14, 0, 10, 0, 13, STR_00C5, STR_018B_CLOSE_WINDOW}, truelight@0: { WWT_CAPTION, 14, 11, 399, 0, 13, STR_CHEATS, STR_018C_WINDOW_TITLE_DRAG_THIS}, darkvater@176: { WWT_PANEL, 14, 0, 399, 14, 147, 0x0, STR_NULL}, darkvater@176: { WWT_IMGBTN, 14, 0, 399, 14, 147, 0x0, STR_CHEATS_TIP}, darkvater@176: { WIDGETS_END}, truelight@0: }; truelight@0: truelight@0: extern void DrawPlayerIcon(int p, int x, int y); truelight@0: truelight@0: static void CheatsWndProc(Window *w, WindowEvent *e) truelight@0: { truelight@0: switch(e->event) { truelight@0: case WE_PAINT: { truelight@0: int clk = WP(w,def_d).data_1; truelight@0: const CheatEntry *ce = &_cheats_ui[0]; truelight@0: int32 val; truelight@0: int x, y; truelight@0: int i; truelight@0: truelight@0: DrawWindowWidgets(w); truelight@0: truelight@0: DrawStringMultiCenter(200, 25, STR_CHEATS_WARNING, 350); truelight@0: truelight@0: x=0; truelight@0: y=45; truelight@0: truelight@0: for(i=0; i!=lengthof(_cheats_ui); i++,ce++) { truelight@0: truelight@0: DrawSprite((SPR_OPENTTD_BASE + ((*ce->been_used)?67:66)), x+5, y+2); truelight@0: truelight@0: if (ce->type == CE_BOOL) { truelight@0: DrawFrameRect(x+20, y+1, x+30+9, y+9, (*(bool*)ce->variable)?6:4, (*(bool*)ce->variable)?0x20:0); truelight@0: SET_DPARAM16(0, *(bool*)ce->variable ? STR_CONFIG_PATCHES_ON : STR_CONFIG_PATCHES_OFF); truelight@0: truelight@0: } else if (ce->type == CE_CLICK) { truelight@0: DrawFrameRect(x+20, y+1, x+30+9, y+9, 0, (WP(w,def_d).data_1==i*2+1)?0x20:0x00); truelight@0: if(i==0) truelight@0: SET_DPARAM64(0, (int64) 10000000); truelight@0: else truelight@0: SET_DPARAM16(0, false); truelight@0: truelight@0: } else { truelight@0: DrawFrameRect(x+20, y+1, x+20+9, y+9, 3, clk == i*2+1 ? 0x20 : 0); truelight@0: DrawFrameRect(x+30, y+1, x+30+9, y+9, 3, clk == i*2+2 ? 0x20 : 0); truelight@0: DrawStringCentered(x+25, y+1, STR_6819, 0); truelight@0: DrawStringCentered(x+35, y+1, STR_681A, 0); truelight@193: truelight@0: val = ReadCE(ce); dominik@100: dominik@100: // set correct string for switch climate cheat dominik@100: if(ce->str==STR_CHEAT_SWITCH_CLIMATE) dominik@100: val += STR_TEMPERATE_LANDSCAPE; dominik@100: truelight@0: SET_DPARAM16(0, val); dominik@108: dominik@108: // display date for change date cheat dominik@108: if(ce->str==STR_CHEAT_CHANGE_DATE) dominik@108: SET_DPARAM16(0, _date); truelight@193: truelight@0: // draw colored flag for change player cheat truelight@0: if(ce->str==STR_CHEAT_CHANGE_PLAYER) truelight@0: DrawPlayerIcon(_current_player, 156, y+2); truelight@0: truelight@0: } truelight@0: truelight@0: DrawString(50, y+1, ce->str, 0); truelight@0: truelight@0: y+=12; truelight@0: } truelight@0: break; truelight@0: } truelight@0: case WE_CLICK: { truelight@0: const CheatEntry *ce; truelight@0: uint btn = (e->click.pt.y - 46) / 12; truelight@0: int32 val, oval; truelight@0: uint x = e->click.pt.x; truelight@0: truelight@0: // not clicking a button? truelight@0: if(!IS_INT_INSIDE(x, 20, 40) || btn>=lengthof(_cheats_ui)) truelight@0: break; truelight@0: truelight@0: ce = &_cheats_ui[btn]; truelight@0: oval = val = ReadCE(ce); truelight@0: truelight@0: *ce->been_used = true; truelight@0: truelight@0: switch(ce->type) { truelight@0: case CE_BOOL: { truelight@0: val ^= 1; truelight@0: if (ce->click_proc != NULL) truelight@0: ce->click_proc(val, 0); truelight@0: break; truelight@0: } truelight@0: truelight@0: case CE_CLICK: { truelight@0: ce->click_proc(val, 0); truelight@0: WP(w,def_d).data_1 = btn * 2 + 1; truelight@0: break; truelight@0: } truelight@0: truelight@0: default: { truelight@0: if (x >= 30) { truelight@0: //increase truelight@0: val += ce->step; truelight@0: if (val > ce->max) val = ce->max; truelight@0: } else { truelight@0: // decrease truelight@0: val -= ce->step; truelight@0: if (val < ce->min) val = ce->min; truelight@0: } truelight@0: truelight@0: // take whatever the function returns truelight@0: val = ce->click_proc(val, (x>=30) ? 1 : -1); truelight@0: truelight@0: if (val != oval) truelight@0: WP(w,def_d).data_1 = btn * 2 + 1 + ((x>=30) ? 1 : 0); truelight@0: truelight@0: break; truelight@0: } truelight@0: } truelight@0: truelight@0: if (val != oval) { truelight@0: WriteCE(ce, val); truelight@0: SetWindowDirty(w); truelight@0: } truelight@0: truelight@0: w->flags4 |= 5 << WF_TIMEOUT_SHL; truelight@0: truelight@0: SetWindowDirty(w); truelight@0: } truelight@0: break; truelight@0: case WE_TIMEOUT: truelight@0: WP(w,def_d).data_1 = 0; truelight@0: SetWindowDirty(w); truelight@0: break; truelight@193: } truelight@0: } truelight@0: static const WindowDesc _cheats_desc = { truelight@0: 240, 22, 400, 148, truelight@0: WC_CHEATS,0, truelight@0: WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, truelight@0: _cheat_widgets, truelight@0: CheatsWndProc truelight@0: }; truelight@0: truelight@0: truelight@0: void ShowCheatWindow() truelight@0: { truelight@0: Window *w; truelight@193: truelight@0: DeleteWindowById(WC_CHEATS, 0); truelight@0: w = AllocateWindowDesc(&_cheats_desc); truelight@0: truelight@0: if (w) truelight@0: SetWindowDirty(w); truelight@0: }