Esempio n. 1
0
GLuint LoadShaders(const char * vertex_filepath, const char * fragment_filepath) {
    GLuint ProgramID;
    GLint Result = GL_FALSE;
    int InfoLogLength;

    // Create shaders
    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Load data from file
    std::string VertextShaderCode = GetShaderCodeFromFile(vertex_filepath);
    std::string FragmentShaderCode = GetShaderCodeFromFile(fragment_filepath);

    // Compile and check vertex/fragment shaders
    CompileShader(VertexShaderID, vertex_filepath, VertextShaderCode);
    CheckCompiledShader(VertexShaderID, &Result, &InfoLogLength);
    CompileShader(FragmentShaderID, fragment_filepath, FragmentShaderCode);
    CheckCompiledShader(FragmentShaderID, &Result, &InfoLogLength);

    // Create shader program and link compiled shader with her
    std::cout << "Create shader program..." << std::endl;
    ProgramID = glCreateProgram();
    AttachVertexAndFragmentShaders(ProgramID, VertexShaderID, FragmentShaderID);

    // Check shader program
    CheckProgram(ProgramID, &Result, &InfoLogLength);

    glDetachShader(ProgramID, VertexShaderID);
    glDetachShader(ProgramID, FragmentShaderID);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    return ProgramID;
}
Esempio n. 2
0
/**
 * Vraci program (zkompilovane shadery) pro renderovani uzivatelskeho pohledu
 */
GLuint Shaders::getUserViewProgram() {
	const char *p_s_vertex_shader =
		"#version 330\n"		
		"in vec3 v_pos;\n" // atributy - vstup z dat vrcholu
		"in vec3 v_col;\n" // barva vrcholu
		"\n"
		"uniform mat4 t_modelview_projection_matrix;\n" // parametr shaderu - transformacni matice
		"\n"
		"out vec3 v_color;\n"		
		"\n"
		"void main()\n"
		"{\n"
		"    gl_Position = t_modelview_projection_matrix * vec4(v_pos, 1.0);\n" // musime zapsat pozici
		"    v_color = v_col;\n"
		"}\n";


	const char *p_s_fragment_shader =
		"#version 330\n"
		"in vec3 v_color;\n" // vstupy z vertex shaderu
		"\n"
		"out vec4 frag_color;\n" // vystup do framebufferu
		"\n"
		"void main()\n"
		"{\n"
		"    frag_color = vec4(v_color, 1.0f);\n"
		"}\n";


	// zkompiluje vertex / fragment shader, pripoji je k programu
	n_user_vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(n_user_vertex_shader, 1, &p_s_vertex_shader, NULL);
	glCompileShader(n_user_vertex_shader);
	if(!CheckShader(n_user_vertex_shader, "vertex shader"))
		return false;

	n_user_fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(n_user_fragment_shader, 1, &p_s_fragment_shader, NULL);
	glCompileShader(n_user_fragment_shader);
	if(!CheckShader(n_user_fragment_shader, "fragment shader"))
		return false;
	
	n_user_program_object = glCreateProgram();
	glAttachShader(n_user_program_object, n_user_vertex_shader);
	glAttachShader(n_user_program_object, n_user_fragment_shader);
	
	// nabinduje atributy (propojeni mezi obsahem VBO a vstupem do vertex shaderu)
	glBindAttribLocation(n_user_program_object, 0, "v_pos");
	glBindAttribLocation(n_user_program_object, 1, "v_col");
	
	// nabinduje vystupni promenou (propojeni mezi framebufferem a vystupem fragment shaderu)
	glBindFragDataLocation(n_user_program_object, 0, "frag_color");
	
	// slinkuje program
	glLinkProgram(n_user_program_object);
	if(!CheckProgram(n_user_program_object, "program"))
		return false;
	else
		return n_user_program_object;
}
Esempio n. 3
0
GLuint GLProgramBase::CreateProgram(const std::vector<GLuint> &shaderList) {
	GLuint program = glCreateProgram();

	for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
		glAttachShader(program, shaderList[iLoop]);
	
	glLinkProgram(program);
	CheckProgram(program);

	for( size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
		glDetachShader(program, shaderList[iLoop]);

	return program;
}
Esempio n. 4
0
bool    ImGui_ImplOpenGL3_CreateDeviceObjects()
{
    // Backup GL state
    GLint last_texture, last_array_buffer;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
    glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
    GLint last_vertex_array;
    glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
#endif

    // Parse GLSL version string
    int glsl_version = 130;
    sscanf(g_GlslVersionString, "#version %d", &glsl_version);

    const GLchar* vertex_shader_glsl_120 =
        "uniform mat4 ProjMtx;\n"
        "attribute vec2 Position;\n"
        "attribute vec2 UV;\n"
        "attribute vec4 Color;\n"
        "varying vec2 Frag_UV;\n"
        "varying vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* vertex_shader_glsl_130 =
        "uniform mat4 ProjMtx;\n"
        "in vec2 Position;\n"
        "in vec2 UV;\n"
        "in vec4 Color;\n"
        "out vec2 Frag_UV;\n"
        "out vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* vertex_shader_glsl_300_es =
        "precision mediump float;\n"
        "layout (location = 0) in vec2 Position;\n"
        "layout (location = 1) in vec2 UV;\n"
        "layout (location = 2) in vec4 Color;\n"
        "uniform mat4 ProjMtx;\n"
        "out vec2 Frag_UV;\n"
        "out vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* vertex_shader_glsl_410_core =
        "layout (location = 0) in vec2 Position;\n"
        "layout (location = 1) in vec2 UV;\n"
        "layout (location = 2) in vec4 Color;\n"
        "uniform mat4 ProjMtx;\n"
        "out vec2 Frag_UV;\n"
        "out vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    Frag_UV = UV;\n"
        "    Frag_Color = Color;\n"
        "    gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_120 =
        "#ifdef GL_ES\n"
        "    precision mediump float;\n"
        "#endif\n"
        "uniform sampler2D Texture;\n"
        "varying vec2 Frag_UV;\n"
        "varying vec4 Frag_Color;\n"
        "void main()\n"
        "{\n"
        "    gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_130 =
        "uniform sampler2D Texture;\n"
        "in vec2 Frag_UV;\n"
        "in vec4 Frag_Color;\n"
        "out vec4 Out_Color;\n"
        "void main()\n"
        "{\n"
        "    Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_300_es =
        "precision mediump float;\n"
        "uniform sampler2D Texture;\n"
        "in vec2 Frag_UV;\n"
        "in vec4 Frag_Color;\n"
        "layout (location = 0) out vec4 Out_Color;\n"
        "void main()\n"
        "{\n"
        "    Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
        "}\n";

    const GLchar* fragment_shader_glsl_410_core =
        "in vec2 Frag_UV;\n"
        "in vec4 Frag_Color;\n"
        "uniform sampler2D Texture;\n"
        "layout (location = 0) out vec4 Out_Color;\n"
        "void main()\n"
        "{\n"
        "    Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
        "}\n";

    // Select shaders matching our GLSL versions
    const GLchar* vertex_shader = NULL;
    const GLchar* fragment_shader = NULL;
    if (glsl_version < 130)
    {
        vertex_shader = vertex_shader_glsl_120;
        fragment_shader = fragment_shader_glsl_120;
    }
    else if (glsl_version >= 410)
    {
        vertex_shader = vertex_shader_glsl_410_core;
        fragment_shader = fragment_shader_glsl_410_core;
    }
    else if (glsl_version == 300)
    {
        vertex_shader = vertex_shader_glsl_300_es;
        fragment_shader = fragment_shader_glsl_300_es;
    }
    else
    {
        vertex_shader = vertex_shader_glsl_130;
        fragment_shader = fragment_shader_glsl_130;
    }

    // Create shaders
    const GLchar* vertex_shader_with_version[2] = { g_GlslVersionString, vertex_shader };
    g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL);
    glCompileShader(g_VertHandle);
    CheckShader(g_VertHandle, "vertex shader");

    const GLchar* fragment_shader_with_version[2] = { g_GlslVersionString, fragment_shader };
    g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL);
    glCompileShader(g_FragHandle);
    CheckShader(g_FragHandle, "fragment shader");

    g_ShaderHandle = glCreateProgram();
    glAttachShader(g_ShaderHandle, g_VertHandle);
    glAttachShader(g_ShaderHandle, g_FragHandle);
    glLinkProgram(g_ShaderHandle);
    CheckProgram(g_ShaderHandle, "shader program");

    g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
    g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
    g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position");
    g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV");
    g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");

    // Create buffers
    glGenBuffers(1, &g_VboHandle);
    glGenBuffers(1, &g_ElementsHandle);

    ImGui_ImplOpenGL3_CreateFontsTexture();

    // Restore modified GL state
    glBindTexture(GL_TEXTURE_2D, last_texture);
    glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
    glBindVertexArray(last_vertex_array);
#endif

    return true;
}
bool InitApp() {
	// ---------- OpenGL 설정 초기화 ----------
	// 클리어 색상(배경색) 지정
	glClearColor(1.f, 1.f, 1.f, 1.f);

	glEnable(GL_DEPTH_TEST);

	glDisable(GL_CULL_FACE);
	glFrontFace(GL_CCW);

	glPolygonMode(GL_FRONT, GL_FILL);
	glPolygonMode(GL_BACK, GL_LINE);


	// ---------- 셰이더 생성 및 컴파일 ----------
	// 셰이더 파일 읽기
	std::string vertShaderSource = ReadStringFromFile("BasicShader.glvs");
	std::string fragShaderSource = ReadStringFromFile("BasicShader.glfs");

	// 셰이더 오브젝트 생성
	GLuint vertShaderObj = CreateShader(GL_VERTEX_SHADER, vertShaderSource);
	GLuint fragShaderObj = CreateShader(GL_FRAGMENT_SHADER, fragShaderSource);

	// 셰이더 프로그램 오브젝트 생성
	gShaderProgram = glCreateProgram();

	// 셰이더 프로그램에 버텍스 및 프래그먼트 셰이더 등록
	glAttachShader(gShaderProgram, vertShaderObj);
	glAttachShader(gShaderProgram, fragShaderObj);

	// 셰이더 프로그램과 셰이더 링킹(일종의 컴파일) 그리고 확인
	glLinkProgram(gShaderProgram);
	if (!CheckProgram(gShaderProgram)) {
		glDeleteProgram(gShaderProgram);
		return false;
	}

	// 사용된 셰이더 떼어냄
	glDetachShader(gShaderProgram, vertShaderObj);
	glDetachShader(gShaderProgram, fragShaderObj);

	// 셰이더 삭제
	glDeleteShader(vertShaderObj);
	glDeleteShader(fragShaderObj);


	// ---------- 정점 어트리뷰트 버퍼 생성 ----------
	// 정점 정의
	gVertices = {
		glm::vec3(-0.5f, -0.5f, 0.f), glm::vec3(0.5f, -0.5f, 0.f), glm::vec3(0.5f, 0.5f, 0.f)
	};

	// OpenGL 4.5 이전의 버퍼 생성 방식.
	// 정점 버퍼 생성
	//glGenBuffers(1, &gVertexBufferObject);

	// 정점 버퍼 바인딩 및 데이터 등록
	//glBindBuffer(GL_ARRAY_BUFFER, gVertexBufferObject);
	//glBufferData(GL_ARRAY_BUFFER, gVertices.size()*sizeof(glm::vec3), &gVertices[0], GL_STATIC_DRAW);

	// OpenGL 4.5의 버퍼 생성 방식. (Direct State Access 기능으로 가능해짐)
	glCreateBuffers(1, &gVertexBufferObject);
	glNamedBufferData(gVertexBufferObject, gVertices.size()*sizeof(glm::vec3), &gVertices[0], GL_STATIC_DRAW);

	return true;
}
Esempio n. 6
0
/**
 * Vraci program (zkompilovane shadery) pro renderovani nahledoveho krize
 */
GLuint Shaders::getPreviewProgram() {
	const char *p_s_vertex_shader =
		"#version 330\n"		
		"in vec3 v_pos;\n" // atributy - vstup z dat vrcholu
		"in vec2 v_tex;\n" // souradnice textury
		"\n"
		"uniform mat4 t_modelview_projection_matrix;\n" // parametr shaderu - transformacni matice
		"\n"
		"out vec2 v_texcoord, v_normal_tex;\n" 		
		"\n"
		"void main()\n"
		"{\n"
		"    gl_Position = t_modelview_projection_matrix * vec4(v_pos, 1.0);\n" // musime zapsat pozici
		"	 v_texcoord = v_tex;\n"
		"    v_normal_tex = v_tex * 2.0 - 1.0;\n"		
		"}\n";


	const char *p_s_fragment_shader =
		"#version 330\n"
		"in vec2 v_texcoord, v_normal_tex;\n"
		"\n"
		"out vec4 frag_color;\n" // vystup do framebufferu
		"\n"
		"uniform sampler2D n_tex;\n"
		"\n"
		"void main()\n"
		"{\n"			
		/*
		"    vec4 tex_color = vec4(0.0);"
		"    if(v_texcoord.y >= 0.25 && v_texcoord.y <= 0.75) {"
		"        if(v_texcoord.x < 0.25)"
		"            tex_color = texture(n_tex, (v_texcoord + vec2(0, -.25)) * vec2(0.25/0.25, 0.66667/0.5));"
		"        else if(v_texcoord.x < 0.75)"
		"            tex_color = texture(n_tex, (v_texcoord + vec2(0, -.25)) * vec2(0.5/0.5, 0.66667/0.5));"
		"        else"
		"            tex_color = texture(n_tex, (v_texcoord + vec2(0, -.25)) * vec2(0.25/0.25, 0.66667/0.5));"
		"    } else if(v_texcoord.y < 0.25 && v_texcoord.x >= 0.25 && v_texcoord.x <= 0.75)"
		"        tex_color = texture(n_tex, (v_texcoord + vec2(-.25, 0)) * vec2(0.5/0.5, 0.33333/0.25) + vec2(0.5, 0.66667));"
		"    else if(v_texcoord.y > 0.75 && v_texcoord.x >= 0.25 && v_texcoord.x <= 0.75)"
		"        tex_color = texture(n_tex, (v_texcoord + vec2(-0.25, -.75)) * vec2(0.5/0.5, 0.33333/0.25) + vec2(0.0, 0.66667));"
		"    else discard;"	
		*/
		"    vec4 tex_color = texture(n_tex, v_texcoord);\n"
		/*		
		"    vec4 tex_color = texture(n_tex, v_texcoord) * .5;//vec4(0.0);\n" // precte texturu krabice
		"    float f_tex_length = length(v_normal_tex);\n"
		"    vec3 v_ray = vec3(v_normal_tex, sqrt(1 - f_tex_length));\n"
		"    if(f_tex_length > 1.0)\n"
		"        discard;\n"
		"    vec3 v_ray_abs = abs(v_ray);\n"
		"    if(v_ray.z > v_ray_abs.x && v_ray.z > v_ray_abs.y)\n" // dopredu
		"        tex_color = texture(n_tex, ((v_ray.xy / v_ray.z) * .5 + .5) * vec2(0.5, 0.66667) + vec2(0.25, 0.0));\n"
		"    else if(v_ray_abs.x > v_ray_abs.y) {\n"
		"        if(v_ray.x < 0)\n" // vlevo
		"            tex_color = texture(n_tex, ((v_ray.yz / v_ray.x) * vec2(0.5, 0.5) + vec2(0.5, 0.5)) * vec2(-0.25, -0.66667) + vec2(0.25, 0.66667));\n"
		"        else\n" // vpravo
		"            tex_color = texture(n_tex, ((v_ray.yz / v_ray.x) * vec2(-0.5, 0.5) + vec2(0.5, 0.5)) * vec2(0.25, 0.66667) + vec2(0.75, 0.0));\n"
		"    } else {\n"
		"        if(v_ray.y < 0)\n" // nahoru
		"            tex_color = texture(n_tex, ((v_ray.xz / v_ray.y) * vec2(0.5, 0.5) + vec2(0.5, 0.5)) * vec2(-0.5, -0.33333) + vec2(1.0, 1.0));\n"
		"        else\n" // dolu
		"            tex_color = texture(n_tex, ((v_ray.xz / v_ray.y) * vec2(0.5, -0.5) + vec2(0.5, 0.5)) * vec2(0.5, 0.33333) + vec2(0, 0.66667));\n"
		"    }\n"
		*/
		"    frag_color = tex_color;\n"
		"}\n";


	// zkompiluje vertex / fragment shader, pripoji je k programu
	n_preview_vertex_shader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(n_preview_vertex_shader, 1, &p_s_vertex_shader, NULL);
	glCompileShader(n_preview_vertex_shader);
	if(!CheckShader(n_preview_vertex_shader, "vertex shader"))
		return false;

	n_preview_fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(n_preview_fragment_shader, 1, &p_s_fragment_shader, NULL);
	glCompileShader(n_preview_fragment_shader);
	if(!CheckShader(n_preview_fragment_shader, "fragment shader"))
		return false;
	
	n_preview_program_object = glCreateProgram();
	glAttachShader(n_preview_program_object, n_preview_vertex_shader);
	glAttachShader(n_preview_program_object, n_preview_fragment_shader);
	
	// nabinduje atributy (propojeni mezi obsahem VBO a vstupem do vertex shaderu)
	glBindAttribLocation(n_preview_program_object, 0, "v_pos");
	glBindAttribLocation(n_preview_program_object, 2, "v_tex");
	
	// nabinduje vystupni promenou (propojeni mezi framebufferem a vystupem fragment shaderu)
	glBindFragDataLocation(n_preview_program_object, 0, "frag_color");
	
	// slinkuje program
	glLinkProgram(n_preview_program_object);
	if(!CheckProgram(n_preview_program_object, "program"))
		return false;
	else
		return n_preview_program_object;
}
Esempio n. 7
0
/**
 * The main capsule building interface.
 *
 * Programs refers to the Manned capsule programs, specifically the
 * ones where astronauts may be assigned. This has the main control
 * loop for the capsule building user interface.
 *
 * \param plr  the country running the program
 * \param prog  the capsule style
 */
void Programs(char plr, char prog)
{
    int i, max, chk, tst;
    int now2 = 0, count = 0, grp = 0, BarA = 0;
    int M[100], CrewCount[8];
    char ksel = 0;

    helpText = "i036";
    keyHelpText = "k036";

    for (i = 0; i < 100; i++) {
        M[i] = -1;
    }

    if (prog > 4) {
        max = 4;
    } else if (prog == 4) {
        max = 3;
    } else {
        max = prog;
    }

    music_start(M_PRGMTRG);
    DrawProgs(plr, prog);
    Flts(0, 0);

    for (i = 0; i < ASTRONAUT_CREW_MAX; i++) {
        CrewCount[i] = Data->P[plr].CrewCount[prog][i];

        if (CrewCount[i] == 0) {
            FltsTxt(i, 8);
        }

        if (CrewCount[i] < max && CrewCount[i] != 0) {
            FltsTxt(i, 9);
        }

        if (CrewCount[i] == max) {
            FltsTxt(i, 1);
        }
    }

    for (i = 0; i < Data->P[plr].AstroCount; i++) {
        if (Data->P[plr].Pool[i].Assign == prog
            && Data->P[plr].Pool[i].Crew == 0) {
            M[count++] = i;
        }
    }

    ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
    DispLeft(plr, BarA, count, now2, &M[0]);
    NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
               Data->P[plr].Crew[prog][grp][1],
               Data->P[plr].Crew[prog][grp][2], Data->P[plr].Crew[prog][grp][3]);
    FadeIn(2, 10, 0, 0);

    chk = CheckProgram(plr, prog);

    if (chk == 0) {
        if (plr == 0) {
            Help("i113");
        } else {
            Help("i114");
        }

        music_stop();
        return;
    }

    WaitForMouseUp();

    while (1) {
        key = 0;
        GetMouse();

        for (i = 0; i < 8; i++) {
            // Right Select Box
            if (x >= 27 && y >= (131 + i * 8) && x <= 151
                && y <= (137 + i * 8) && mousebuttons > 0
                && (now2 - BarA + i) <= (count - 1)) {
                // Left
                now2 -= BarA;
                now2 += i;
                BarA = i;
                fill_rectangle(26, 129, 153, 195, 0);
                DispLeft(plr, BarA, count, now2, &M[0]);
                ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                BarSkill(plr, BarA, now2, &M[0]);
                WaitForMouseUp();
                ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                DispLeft(plr, BarA, count, now2, &M[0]);
            }
        }

        if (mousebuttons > 0 || key > 0) {  /* Gameplay */
            if (((x >= 6 && y >= 130 && x <= 18 && y <= 161
                  && mousebuttons > 0) || key == UP_ARROW)
                && count > 0) {
                /* Lft Up */
                InBox(6, 130, 18, 161);

                for (i = 0; i < 50; i++) {
                    key = 0;
                    GetMouse();
                    delay(10);

                    if (mousebuttons == 0) {

                        if (BarA == 0)
                            if (now2 > 0) {
                                now2--;
                                fill_rectangle(26, 129, 153, 195, 0);
                                ShBox(26, 130 + BarA * 8, 152,
                                      138 + BarA * 8);
                                DispLeft(plr, BarA, count, now2, &M[0]);
                            }

                        if (BarA > 0) {
                            fill_rectangle(26, 129, 153, 195, 0);
                            BarA--;
                            now2--;
                            ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                            DispLeft(plr, BarA, count, now2, &M[0]);
                        }

                        i = 51;
                    }
                }

                while (mousebuttons == 1 || key == UP_ARROW) {
                    delay(100);

                    if (BarA == 0)
                        if (now2 > 0) {
                            now2--;
                            fill_rectangle(26, 129, 153, 195, 0);
                            ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                            DispLeft(plr, BarA, count, now2, &M[0]);
                        }

                    if (BarA > 0) {
                        fill_rectangle(26, 129, 153, 195, 0);
                        BarA--;
                        now2--;
                        ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                        DispLeft(plr, BarA, count, now2, &M[0]);
                    }

                    key = 0;

                    GetMouse();
                }

                OutBox(6, 130, 18, 161);
                delay(10);
            } else if (((x >= 6 && y >= 163 && x <= 18 && y <= 194
                         && mousebuttons > 0) || key == DN_ARROW)
                       && count > 0) {
                /* Lft Dwn */
                InBox(6, 163, 18, 194);

                for (i = 0; i < 50; i++) {
                    key = 0;
                    GetMouse();
                    delay(10);

                    if (mousebuttons == 0) {

                        if (BarA == 7)
                            if (now2 < count - 1) {
                                now2++;
                                fill_rectangle(26, 129, 153, 195, 0);
                                ShBox(26, 130 + BarA * 8, 152,
                                      138 + BarA * 8);
                                DispLeft(plr, BarA, count, now2, &M[0]);
                            }

                        if (BarA < 7)
                            if (now2 < count - 1) {
                                fill_rectangle(26, 129, 153, 195, 0);
                                BarA++;
                                now2++;
                                ShBox(26, 130 + BarA * 8, 152,
                                      138 + BarA * 8);
                                DispLeft(plr, BarA, count, now2, &M[0]);
                            }

                        i = 51;
                    }
                }

                while (mousebuttons == 1 || key == DN_ARROW) {
                    delay(100);

                    if (BarA == 7)
                        if (now2 < count - 1) {
                            now2++;
                            fill_rectangle(26, 129, 153, 195, 0);
                            ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                            DispLeft(plr, BarA, count, now2, &M[0]);
                        }

                    if (BarA < 7)
                        if (now2 < count - 1) {
                            fill_rectangle(26, 129, 153, 195, 0);
                            BarA++;
                            now2++;
                            ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                            DispLeft(plr, BarA, count, now2, &M[0]);
                        }

                    key = 0;

                    GetMouse();
                }

                //WaitForMouseUp();
                OutBox(6, 163, 18, 194);
            } else if (key == K_HOME) {
                fill_rectangle(26, 129, 153, 195, 0);
                BarA = 0;
                now2 = 0;
                ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                DispLeft(plr, BarA, count, now2, &M[0]);
            } else if (key == K_END) {
                fill_rectangle(26, 129, 153, 195, 0);
                BarA = MIN(count - 1, 7);
                now2 = count - 1;
                ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                DispLeft(plr, BarA, count, now2, &M[0]);
            } else if (key == 'S') {
                // Show Skill
                ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);
                BarSkill(plr, BarA, now2, &M[0]);
            } else if (((x >= 4 && y >= 86 && x <= 12 && y <= 92
                         && mousebuttons > 0) || key == '1')
                       && CrewCount[grp] >= 1) {
                /* Display Man 1 */
                InBox(4, 86, 12, 92);
                AstLevel(plr, prog, grp, 0);
                OutBox(4, 86, 12, 92);
            } else if (((x >= 4 && y >= 95 && x <= 12 && y <= 101
                         && mousebuttons > 0) || key == '2') && prog >= 2
                       && CrewCount[grp] >= 2) {
                /* Display Man 2 */
                InBox(4, 95, 12, 101);
                AstLevel(plr, prog, grp, 1);
                OutBox(4, 95, 12, 101);
            } else if (((x >= 4 && y >= 104 && x <= 12 && y <= 110
                         && mousebuttons > 0) || key == '3') && prog >= 3
                       && CrewCount[grp] >= 3) {
                /* Display Man 3 */
                InBox(4, 104, 12, 110);
                AstLevel(plr, prog, grp, 2);
                OutBox(4, 104, 12, 110);
            } else if (((x >= 4 && y >= 113 && x <= 12 && y <= 119
                         && mousebuttons > 0) || key == '4') && prog >= 5
                       && CrewCount[grp] >= 4) {
                /* Display Man 4 */
                InBox(4, 113, 12, 119);
                AstLevel(plr, prog, grp, 3);
                OutBox(4, 113, 12, 119);
            } else if (key == 'C') {
                ClearIt();
                ksel = grp;        //save old flt crew

                if (grp == 7) {
                    grp = 0;
                } else {
                    ++grp;
                }

                Flts(ksel, grp);
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);

                if (key > 0) {
                    delay(150);
                }
            } else if (x >= 164 && y >= 139 && x <= 238 && y <= 151
                       && mousebuttons > 0) {
                /* Flt Crew I */
                ClearIt();
                Flts(grp, 0);
                grp = 0;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (x >= 164 && y >= 154 && x <= 238 && y <= 166
                       && mousebuttons > 0) {
                /* Flt Crew II */
                ClearIt();
                Flts(grp, 1);
                grp = 1;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (x >= 164 && y >= 169 && x <= 238 && y <= 181
                       && mousebuttons > 0) {
                /* Flt Crew III */
                ClearIt();
                Flts(grp, 2);
                grp = 2;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (x >= 164 && y >= 184 && x <= 238 && y <= 196
                       && mousebuttons > 0) {
                /* Flt Crew IV */
                ClearIt();
                Flts(grp, 3);
                grp = 3;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (x >= 241 && y >= 139 && x <= 315 && y <= 151
                       && mousebuttons > 0) {
                /* Flt Crew V */
                ClearIt();
                Flts(grp, 4);
                grp = 4;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (x >= 241 && y >= 154 && x <= 315 && y <= 166
                       && mousebuttons > 0) {
                /* Flt Crew VI */
                ClearIt();
                Flts(grp, 5);
                grp = 5;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (x >= 241 && y >= 169 && x <= 315 && y <= 181
                       && mousebuttons > 0) {
                /* Flt Crew VII */
                ClearIt();
                Flts(grp, 6);
                grp = 6;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (x >= 241 && y >= 184 && x <= 315 && y <= 196
                       && mousebuttons > 0) {
                /* Flt Crew VIII */
                ClearIt();
                Flts(grp, 7);
                grp = 7;
                NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                           Data->P[plr].Crew[prog][grp][1],
                           Data->P[plr].Crew[prog][grp][2],
                           Data->P[plr].Crew[prog][grp][3]);
                WaitForMouseUp();
            } else if (((x >= 245 && y >= 88 && x <= 314 && y <= 100
                         && mousebuttons > 0) || key == 'A')
                       && CrewCount[grp] < max) {
                /* Assign 'Naut */
                if (Data->P[plr].Crew[prog][grp][CrewCount[grp]] == 0
                    && count > 0) {
                    InBox(245, 88, 314, 100);
                    Data->P[plr].Crew[prog][grp][CrewCount[grp]] = M[now2] + 1;

                    AstNames(CrewCount[grp], &Data->P[plr].Pool[M[now2]].Name[0],
                             Data->P[plr].Pool[M[now2]].Mood);
                    Data->P[plr].Pool[M[now2]].Crew = grp + 1;
                    Data->P[plr].Pool[M[now2]].Task = CrewCount[grp];
                    Data->P[plr].Pool[M[now2]].Unassigned = 1;

                    for (i = now2; i < count; i++) {
                        M[i] = M[i + 1];
                    }

                    M[i] = -1;
                    count--;

                    if (now2 == count) {
                        if (now2 > 0) {
                            now2--;
                        }

                        if (BarA > 0) {
                            BarA--;
                        }
                    }

                    fill_rectangle(26, 129, 153, 195, 0);

                    ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);

                    DispLeft(plr, BarA, count, now2, &M[0]);

                    CrewCount[grp]++;

                    Data->P[plr].CrewCount[prog][grp] = CrewCount[grp];

                    if (CrewCount[grp] == max) {
                        FltsTxt(grp, 1);
                    } else {
                        FltsTxt(grp, 9);
                    }

                    NewAstList(plr, prog, Data->P[plr].Crew[prog][grp][0],
                               Data->P[plr].Crew[prog][grp][1],
                               Data->P[plr].Crew[prog][grp][2],
                               Data->P[plr].Crew[prog][grp][3]);
                    WaitForMouseUp();

                    if (key > 0) {
                        delay(150);
                    }

                    OutBox(245, 88, 314, 100);
                }                 /* End outer if */
            } else if ((x >= 245 && y >= 106 && x <= 314 && y <= 118
                        && mousebuttons > 0) || key == 'B') {
                /* Break Group */
                tst = Data->P[plr].Crew[prog][grp][0] - 1;

                /* If the crew is assigned to a mission, create an alert
                 * that it cannot be broken while the mission is planned. */
                if (Data->P[plr].Pool[tst].Prime > 0) {
                    OutBox(245, 106, 314, 118);
                    /* Copy the screen area into a buffer before drawing
                     * the dialog so it can be repainted after the dialog
                     * is dismissed */
                    display::LegacySurface buffer(170, 131);
                    buffer.copyFrom(display::graphics.legacyScreen(), 75, 43, 244, 173);
                    /* Draw the alert message */
                    ShBox(75, 43, 244, 173);
                    IOBox(81, 152, 238, 167);
                    InBox(81, 70, 238, 113);
                    fill_rectangle(82, 71, 237, 112, 7 + 3 * plr);
                    display::graphics.setForegroundColor(1);
                    draw_heading(118, 50, "PROBLEM", 0, -1);
                    draw_string(136, 162, "CONTINUE");
                    display::graphics.setForegroundColor(11);
                    draw_string(88, 80, "FLIGHT CREW ");
                    draw_number(0, 0, grp + 1);
                    draw_string(0, 0, " IS ALREADY");
                    draw_string(88, 88, "ASSIGNED TO THE ");

                    if (Data->P[plr].Pool[tst].Prime == 4
                        || Data->P[plr].Pool[tst].Prime == 3) {
                        draw_string(0, 0, "PRIMARY");
                    } else {
                        draw_string(0, 0, "BACKUP");
                    }

                    draw_string(88, 96, "CREW OF A CURRENT MISSION:");
                    draw_string(88, 104, "CANNOT BREAK THIS CREW.");

                    WaitForMouseUp();
                    i = 1;

                    while (i == 1) {
                        key = 0;
                        GetMouse();

                        if (mousebuttons > 0 || key > 0) {
                            if ((x >= 83 && y >= 154 && x <= 236 && y <= 165
                                 && mousebuttons != 0) || key == K_ENTER) {
                                InBox(83, 154, 236, 165);
                                WaitForMouseUp();
                                OutBox(83, 154, 236, 165);
                                /* Closing the alert message.
                                 * Redraw the screen behind it from buffer */
                                buffer.copyTo(display::graphics.legacyScreen(),
                                              75, 43);
                                i = 2;
                            }
                        }
                    }
                } else if (Data->P[plr].Crew[prog][grp][0] != 0) {
                    InBox(245, 106, 314, 118);

                    while (CrewCount[grp] > 0) {
                        M[count] =
                            Data->P[plr].Crew[prog][grp][CrewCount[grp] - 1] - 1;
                        Data->P[plr].Crew[prog][grp][CrewCount[grp] - 1] = 0;
                        Data->P[plr].Pool[M[count]].Crew = 0;
                        Data->P[plr].Pool[M[count]].Moved = 0;
                        Data->P[plr].Pool[M[now2]].Unassigned = 0;
                        CrewCount[grp]--;
                        count++;
                    }

                    ClearIt();

                    fill_rectangle(26, 129, 153, 195, 0);

                    FltsTxt(grp, 8);

                    ShBox(26, 130 + BarA * 8, 152, 138 + BarA * 8);

                    DispLeft(plr, BarA, count, now2, &M[0]);

                    for (i = 1; i < 5; i++) {
                        DrawPosition(prog, i);
                    }

                    WaitForMouseUp();
                    OutBox(245, 106, 314, 118);
                }
            } else if ((x >= 245 && y >= 5 && x <= 314 && y <= 17
                        && mousebuttons > 0) || key == K_ENTER) {
                /* Exit */
                InBox(245, 5, 314, 17);
                WaitForMouseUp();

                if (key > 0) {
                    delay(150);
                }

                OutBox(245, 5, 314, 17);
                delay(10);

                for (i = 0; i < 8; i++) {
                    if (CrewCount[i] < max)
                        while (CrewCount[i] > 0) {
                            M[count] =
                                Data->P[plr].Crew[prog][i][CrewCount[i] - 1] - 1;
                            Data->P[plr].Crew[prog][i][CrewCount[i] - 1] = 0;
                            Data->P[plr].Pool[M[count]].Crew = 0;
                            Data->P[plr].CrewCount[prog][i] = 0;
                            CrewCount[i]--;
                            count++;
                        }

                    Data->P[plr].CrewCount[prog][i] = CrewCount[i];
                }

                for (i = 0; i < count; i++) {
                    Data->P[plr].Pool[M[i]].Assign = 0;
                }

                music_stop();

                return;            /* Done */
            }
        }
    }
}