summaryrefslogtreecommitdiff
path: root/source/presentation/Screen.cpp
blob: 0f5ba4c93f31452b42285a56e81a3721e3acc628 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "Screen.h"

Screen::Screen(unsigned int screenWidth, unsigned int screenHeight, bool fullscreen)
    :_exitClicked(false),
    _screenWidth(screenWidth),
    _screenHeight(screenHeight),
    _gameAreaWidth(_screenWidth*0.75),
    _infoPanelWidth(_screenWidth - _gameAreaWidth)
{
    if (fullscreen)
    {
        al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW);
        if (!resolutionSupported())
        {
            al_show_native_message_box(NULL, "Fatal error", "Fatal error", "The fullscreen resolution specified in config.txt is not supported by your system. Please open config.txt and change the resolution to a supported resolution, or change fullscreen to false.", NULL, ALLEGRO_MESSAGEBOX_ERROR);
            throw BadResolution();
        }
    }
    else
    {
        al_set_new_display_flags(ALLEGRO_WINDOWED);
        //need to add error checking for windows that are way too big
    }

    al_set_new_display_option(ALLEGRO_VSYNC, 1, ALLEGRO_SUGGEST);

    _display = al_create_display(_screenWidth, _screenHeight);

    al_hide_mouse_cursor(_display);
    _windowEvents = al_create_event_queue();
    al_register_event_source(_windowEvents, al_get_display_event_source(_display));
    //used so that ESC can be pressed to exit.
    al_register_event_source(_windowEvents, al_get_keyboard_event_source());

    _font = al_load_font("junction 02.ttf", _screenWidth/10, 0);
    if (_font == NULL)
    {
        al_show_native_message_box(NULL, "Fatal error", "Fatal error", "The file 'junction 02.ttf' was not found. Ensure that it is located in the working directory.", NULL, ALLEGRO_MESSAGEBOX_ERROR);
        al_destroy_event_queue(_windowEvents);
        al_destroy_display(_display);
        throw InstallFailure();
    }

    ALLEGRO_BITMAP* front = al_get_backbuffer(_display);
    al_flip_display();
    ALLEGRO_BITMAP* back = al_get_backbuffer(_display);

    _panels.push_back(new GamePanel(back, front, 0, 0, _gameAreaWidth, _screenHeight));
    _panels.push_back(new InfoPanel(back, front, _gameAreaWidth, 0, _infoPanelWidth, _screenHeight));
}

Screen::~Screen()
{
    for (vector<ScreenPanel*>::iterator iter = _panels.begin(); iter!=_panels.end(); ++iter)
    {
        delete (*iter);
    }
    _panels.clear();

    al_destroy_font(_font);
    al_destroy_event_queue(_windowEvents);
    al_destroy_display(_display);
}

string Screen::getLevel()
{
    string result("");
    ALLEGRO_FILECHOOSER* filechooser = al_create_native_file_dialog(".", "Choose your level", "*.lvl",ALLEGRO_FILECHOOSER_FILE_MUST_EXIST);
    al_show_native_file_dialog(_display, filechooser);
    if (al_get_native_file_dialog_count(filechooser)==0)
    {
        _exitClicked = true;
    }
    else
    {
        result = al_get_native_file_dialog_path(filechooser, 0);
    }

    al_destroy_native_file_dialog(filechooser);
    return result;
}

void Screen::draw(const Maze& maze, const list<PlayerCar>& players, const list<EnemyCar>& enemies, const list<Checkpoint>& checkpoints, const list<Rock>& rocks, const list<Smokescreen>& smokescreens, const list<DestroyedObjectPopup>& popups)
{
    for (vector<ScreenPanel*>::iterator iter =  _panels.begin(); iter!=_panels.end(); ++iter)
    {
        (*iter)->draw(maze, players, enemies, checkpoints, rocks, smokescreens, popups);
    }
    flip();
}

void Screen::flip()
{
    al_flip_display();
    for (vector<ScreenPanel*>::iterator iter =  _panels.begin(); iter!=_panels.end(); ++iter)
    {
        (*iter)->flip();
    }
}

void Screen::drawWin()
{
    flip();

    ALLEGRO_COLOR transBlack = al_map_rgba(0,0,0,200);
    al_draw_filled_rectangle(0,0,_screenWidth,_screenHeight, transBlack);

    ALLEGRO_COLOR textColour = al_map_rgb(255,255,255);
    al_draw_text(_font, textColour, _screenWidth/2, _screenHeight/2, ALLEGRO_ALIGN_CENTRE , "You win!");

    flip();
}

void Screen::drawLoss()
{
    flip();

    ALLEGRO_COLOR transBlack = al_map_rgba(0,0,0,200);
    al_draw_filled_rectangle(0,0,_screenWidth,_screenHeight, transBlack);

    ALLEGRO_COLOR textColour = al_map_rgb(255,255,255);
    al_draw_text(_font, textColour, _screenWidth/2, _screenHeight/2, ALLEGRO_ALIGN_CENTRE , "You lose!");

    flip();
}

bool Screen::exitClicked()
{
    if (_exitClicked) return true;

    ALLEGRO_EVENT event;
    while (al_get_next_event(_windowEvents, &event))
    {
        if (event.type==ALLEGRO_EVENT_DISPLAY_CLOSE || (event.type==ALLEGRO_EVENT_KEY_CHAR && event.keyboard.keycode==ALLEGRO_KEY_ESCAPE))
        {
            al_flush_event_queue(_windowEvents);
            _exitClicked = true;
            return true;
        }
    }

    return false;
}

bool Screen::resolutionSupported()
{
    ALLEGRO_DISPLAY_MODE mode;
    for (int i=0; i<al_get_num_display_modes(); ++i)
    {
        al_get_display_mode(i, &mode);

        if (static_cast<unsigned int>(mode.width)==_screenWidth && static_cast<unsigned int>(mode.height)==_screenHeight)
        {
            return true;
        }
    }

    return false;
}