void InvestigationScene::questionWhen() {
    
    removeQuestionElements();
    
    std::string question;
    
    if (currentFilter.strange) {
        
        question = "Did anything strange happen";
        
    } else if (currentFilter.where == NULL) {
        
        question = "Where ";
        
        if (currentFilter.who == activeCharacter) {
            question.append("were you");
        } else {
            question.append("was ");
            question.append(currentFilter.who->name);
        }
        
    } else if (currentFilter.who == NULL) {
        
        question = "Who was in the ";
        question.append(currentFilter.where->name);
    }
    
    question.append(" between ... ?");
    
    questionLabel->setText(question.c_str());
    
    Button *button = new Button("<", fontBig, BTN_TXT_COLOR, "res/btn_small.png", "res/btn_small_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(260, 300));
    button->setTag(401);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button(">", fontBig, BTN_TXT_COLOR, "res/btn_small.png", "res/btn_small_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(540, 300));
    button->setTag(402);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    char buff[20];
    sprintf(buff, "%s and %s", timeToString(currentFilter.timeStart + START_TIME, false).c_str(), timeToString(currentFilter.timeEnd + START_TIME, false).c_str());
    
    whenLabel->setText(buff);
    whenLabel->setVisible(true);
    
    askQuestionButton->setEnabled(true);
    askQuestionButton->setVisible(true);
}
Пример #2
0
    /*
     * device_Line should have the side-effect that a single
     * line is drawn (from x1,y1 to x2,y2)
     *
     * R_GE_gcontext parameters that should be honoured (if possible):
     *   col, gamma, lty, lwd
     */
static void SWF_Line( double x1, double y1, double x2, 
	double y2, const pGEcontext plotParams, pDevDesc deviceInfo )
{
	/* Shortcut pointers to variables of interest. */
	swfDevDesc *swfInfo = (swfDevDesc *) deviceInfo->deviceSpecific;
	
	//If debugging, print info to log file
	if(swfInfo->debug == TRUE){
		fprintf(swfInfo->logFile,
			"SWF_Line: Drawing line from (%6.1f, %6.1f) to (%6.1f, %6.1f)\n",
			x1,y1,x2,y2);
		fflush(swfInfo->logFile);
	}
	
	SWFShape line = newSWFShape();
	/*Ming (0,0) is the top left, convert to R (0,0) at bottom left*/
	y1 = deviceInfo->top - y1;
	y2 = deviceInfo->top - y2;
	
	
	SWFShape_movePenTo(line, x1, y1);
	
	if( plotParams->col != R_RGBA(255, 255, 255, 0) )
		SWF_SetLineStyle(line, plotParams, swfInfo);
	
	//Respect lty	
	SWF_drawStyledLineTo(line, x2, y2, plotParams->lty);
	

	SWFDisplayItem lined = SWFMovie_add(swfInfo->m, (SWFBlock) line);
	
	addToDisplayList( lined );
	
}
Пример #3
0
    /*
     * device_Circle should have the side-effect that a
     * circle is drawn, centred at the given location, with
     * the given radius.
     * (If the device has non-square pixels, 'radius' should
     * be interpreted in the units of the x direction.)
     * The border of the circle should be
     * drawn in the given "col", and the circle should be
     * filled with the given "fill" colour.
     * If "col" is NA_INTEGER then no border should be drawn
     * If "fill" is NA_INTEGER then the circle should not
     * be filled.
     *
     * R_GE_gcontext parameters that should be honoured (if possible):
     *   col, fill, gamma, lty, lwd
     */	
static void SWF_Circle( double x, double y, double r,
		const pGEcontext plotParams, pDevDesc deviceInfo ){
	
	/* Shortcut pointers to variables of interest. */
	swfDevDesc *swfInfo = (swfDevDesc *) deviceInfo->deviceSpecific;
	
	if( swfInfo->debug == TRUE ){
		fprintf(swfInfo->logFile,
			"SWF_Circle: Drawing Circle at x = %f, y = %f, r = %f\n",
			x,y,r);
		fflush(swfInfo->logFile);
	}
	
	SWFShape circle;
	circle = newSWFShape();
	
	SWFShape_movePenTo(circle, x, y);
	/*Ming (0,0) is the top left, convert to R (0,0) at bottom left*/
	y = deviceInfo->top - y;

	// this is causing the shapes not to be drawn???
	if( plotParams->fill != R_RGBA(255, 255, 255, 0) )
		SWF_SetFill( circle,  plotParams, swfInfo);

	if( plotParams->col != R_RGBA(255, 255, 255, 0) )
		SWF_SetLineStyle( circle,  plotParams, swfInfo);
	
	// draws a circle with radius r 
	// centered at (x,y) into shape circle

	double a = r * 0.414213562; 
	// = tan(22.5 deg)

	double b = r * 0.707106781; 
	// = sqrt(2)/2 = sin(45 deg)

	SWFShape_movePenTo(circle, x + r, y);

	SWFShape_drawCurveTo(circle, x+r, y-a, x+b, y-b); 
	SWFShape_drawCurveTo(circle, x+a, y-r, x  , y-r); 
	SWFShape_drawCurveTo(circle, x-a, y-r, x-b, y-b); 
	SWFShape_drawCurveTo(circle, x-r, y-a, x-r, y  ); 
	SWFShape_drawCurveTo(circle, x-r, y+a, x-b, y+b); 
	SWFShape_drawCurveTo(circle, x-a, y+r, x  , y+r); 
	SWFShape_drawCurveTo(circle, x+a, y+r, x+b, y+b); 
	SWFShape_drawCurveTo(circle, x+r, y+a, x+r, y  );
	
	
	// I would like to use this function but the circles 
	// drawn with it are funky
	//SWFShape_drawCircle(circle, r);

	SWFDisplayItem circled = SWFMovie_add(swfInfo->m, (SWFBlock) circle);

	addToDisplayList( circled );
			
}
Пример #4
0
    /*
     * device_Text should have the side-effect that the
     * given text is drawn at the given location.
     * The text should be rotated according to rot (degrees)
     *
     * R_GE_gcontext parameters that should be honoured (if possible):
     *   font, cex, ps, col, gamma
     */
static void SWF_Text( double x, double y, const char *str,
		double rot, double hadj, const pGEcontext plotParams, 
		pDevDesc deviceInfo)
{
	/* Shortcut pointers to variables of interest. */
	swfDevDesc *swfInfo = (swfDevDesc *) deviceInfo->deviceSpecific;
	
	if( swfInfo->debug == TRUE ){
		fprintf(swfInfo->logFile,
			"SWF_Text: Writing Text \"%s\"\n", str);
		fflush(swfInfo->logFile);
	}
	
	/* It is possible that this will be very expensive and storing 
	 * a single text object in swfInfo may be better.
	 */
	SWFText text_object = newSWFText();
	SWFDisplayItem text_display;
	/*Ming (0,0) is the top left, convert to R (0,0) at bottom left*/
	y = deviceInfo->top - y;
	
	//found = !strcmp(name, fontlist->family->fxname);
	
	// Tell the text object to use the font previously loaded
	SWFText_setFont(text_object, 
		selectFont(plotParams->fontface, plotParams->fontfamily, swfInfo));
	
	// Set the height of the text
	SWFText_setHeight(text_object, plotParams->ps * plotParams->cex);
	
	// Set the color of the text
	byte red = R_RED(plotParams->col);
	byte green = R_GREEN(plotParams->col);
	byte blue = R_BLUE(plotParams->col);
	byte alpha =  R_ALPHA(plotParams->col);
	SWFText_setColor(text_object, red, green, blue, alpha);
	
	// Add a string to the text object
	SWFText_addString(text_object, str, NULL);
	
	// Add the text object to the movie (at 0,0)
	text_display = SWFMovie_add(swfInfo->m, (SWFBlock) text_object);
	
	addToDisplayList( text_display );
	
	// Move to correct coordinate and rotate
	SWFDisplayItem_moveTo(text_display, x, y);
	SWFDisplayItem_rotate(text_display, rot);
	
			
}
Пример #5
0
	/*
     * device_Polyline should have the side-effect that a
     * series of line segments are drawn using the given x
     * and y values.
     *
     * R_GE_gcontext parameters that should be honoured (if possible):
     *   col, gamma, lty, lwd
     */
static void SWF_Polyline( int n, double *x, double *y,
		pGEcontext plotParams, pDevDesc deviceInfo )
{
	
	/* Shortcut pointers to variables of interest. */
	swfDevDesc *swfInfo = (swfDevDesc *) deviceInfo->deviceSpecific;	
	
	if( swfInfo->debug == TRUE ){
		fprintf(swfInfo->logFile,
			"SWF_Polyline: Drawing Polyline\n");
		fflush(swfInfo->logFile);
	}
	
	SWFShape line;
	line = newSWFShape();
	
	if( plotParams->col != R_RGBA(255, 255, 255, 0) )
		SWF_SetLineStyle(line, plotParams, swfInfo);
	
	
	/*Ming (0,0) is the top left, convert to R (0,0) at bottom left*/
	y[0] = deviceInfo->top - y[0];
	
	/* Start the pen at the first point */
	SWFShape_movePenTo(line, x[0], y[0]);
	
	if( swfInfo->debug == TRUE )
		fprintf(swfInfo->logFile,
			"\t\t(%5.1f,%5.1f)\n",x[0], y[0]);
	
	/* Print coordinates for the middle segments of the line. */
	int i;
	for ( i = 1; i < n; i++ ){
		
		/*Ming (0,0) is the top left, convert to R (0,0) at bottom left*/
		y[i] = deviceInfo->top - y[i];
		
		SWF_drawStyledLineTo(line, x[i], y[i], plotParams->lty);	
		
		if( swfInfo->debug == TRUE )
			fprintf(swfInfo->logFile,
				"\t\t(%5.1f,%5.1f)\n", x[i], y[i]);
	}
	
	SWFDisplayItem lined = SWFMovie_add(swfInfo->m, (SWFBlock) line);
	
	addToDisplayList( lined );

}
void InvestigationScene::questionWhere() {
    
    removeQuestionElements();
    
    questionLabel->setText("Where was ... ?");
    
    std::vector<Character *> characters = mystery->getCharacters();
    std::vector<Character *>::iterator it;
    
    int i = 0;
    
    int px = 400;
    int py = 200;
    
    for (it = characters.begin(); it < characters.end(); ++it) {
        
        Character *character = (Character *) *it;
        
        std::string name = character->name;
        if (character == activeCharacter) {
            name = "You";
        }
        
        Button *button = new Button(name.c_str(), font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
        button->setZOrder(504);
        button->setAnchorPoint(pointMake(0.5, 0.5));
        button->setPosition(pointMake(px, py));
        button->setTag(301 + i);
        button->data = character;
        button->setHandler(this);
        
        addToDisplayList(button);
        questionElements.push_back(button);
        
        py += 36;
        
        i++;
    }
}
void InvestigationScene::questionWho() {
    
    removeQuestionElements();
    
    questionLabel->setText("Who was in the ... ?");
    
    std::vector<Room *> rooms = mystery->getRooms();
    std::vector<Room *>::iterator it;
    
    int i = 0;
    
    int px = 300;
    int py = 200;
    
    for (it = rooms.begin(); it < rooms.end(); ++it) {
        
        Room *room = (Room *) *it;
        
        Button *button = new Button(room->name.c_str(), font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png");
        button->setZOrder(504);
        button->setAnchorPoint(pointMake(0.5, 0.5));
        button->setPosition(pointMake(px, py));
        button->setTag(201 + i);
        button->data = room;
        button->setHandler(this);
        
        addToDisplayList(button);
        questionElements.push_back(button);
        
        py += 36;
        
        if (i == 6) {
            py = 200;
            px += 192;
        }
        
        i++;
    }
}
Пример #8
0
	/*
     * device_Rect should have the side-effect that a
     * rectangle is drawn with the given locations for its
     * opposite corners.  The border of the rectangle
     * should be in the given "col" colour and the rectangle
     * should be filled with the given "fill" colour.
     * If "col" is NA_INTEGER then no border should be drawn
     * If "fill" is NA_INTEGER then the rectangle should not
     * be filled.
     */
static void SWF_Rectangle( double x0, double y0, double x1, 
	double y1, const pGEcontext plotParams, pDevDesc deviceInfo ){

	/* Shortcut pointers to variables of interest. */
	swfDevDesc *swfInfo = (swfDevDesc *) deviceInfo->deviceSpecific;

	if( swfInfo->debug == TRUE ){
		fprintf(swfInfo->logFile,
			"SWF_Rectangle: Drawing Rectangle\n");
		fflush(swfInfo->logFile);
	}
			
	SWFShape rectangle;
	rectangle = newSWFShape();
	/*Ming (0,0) is the top left, convert to R (0,0) at bottom left*/
	y0 = deviceInfo->top - y0;
	y1 = deviceInfo->top - y1;

	if( plotParams->col != R_RGBA(255, 255, 255, 0) )
		SWF_SetLineStyle(rectangle, plotParams, swfInfo);
		
	if( plotParams->fill != R_RGBA(255, 255, 255, 0) )
		SWF_SetFill(rectangle, plotParams, swfInfo);

	/* Start the pen at the first point */
	SWFShape_movePenTo(rectangle, x0, y0);

	/* Draw the four line segments on the rectangle */
	SWF_drawStyledLineTo(rectangle, x0, y1, plotParams->lty);
	SWF_drawStyledLineTo(rectangle, x1, y1, plotParams->lty);
	SWF_drawStyledLineTo(rectangle, x1, y0, plotParams->lty);
	SWF_drawStyledLineTo(rectangle, x0, y0, plotParams->lty);

	SWFDisplayItem rectangled = SWFMovie_add(swfInfo->m, (SWFBlock) rectangle);
	
	addToDisplayList( rectangled );
			
}
Пример #9
0
void SWF_addPlayerControls(double *x, double *y){
	
	//Get the device info by pointer since this can be called from R
	pDevDesc deviceInfo = GEcurrentDevice()->dev;
	
	// Shortcut pointers to variables of interest. 
	swfDevDesc *swfInfo = (swfDevDesc *) deviceInfo->deviceSpecific;
	
	// General variables
	SWFDisplayItem          playd;
	SWFDisplayItem          stopd;
	
	// Fill styles we create
	SWFFillStyle            dark_blue_fill;
	SWFFillStyle            red_fill;
	SWFFillStyle            green_fill;
	
	// Variables used for the play button
	SWFAction               play_action;
	SWFButton               play_button;
	SWFButtonRecord         play_record_down;
	SWFButtonRecord         play_record_up;
	SWFShape                play_shape_down;
	SWFShape                play_shape_up;
	
	// Variables used for the stop button
	SWFAction               stop_action;
	SWFButton               stop_button;
	SWFButtonRecord         stop_record_down;
	SWFButtonRecord         stop_record_up;
	SWFShape                stop_shape_down;
	SWFShape                stop_shape_up;
	
	if(swfInfo->haveControls == FALSE){
		
		swfInfo->haveControls = TRUE;
		// Ensure the movie starts out in the "stopped" state
	    SWFMovie_add(swfInfo->m, (SWFBlock) newSWFAction("_root.stop();"));
		
	}
		
	swfInfo->ControlsX = *x;
	swfInfo->ControlsY = deviceInfo->top - *y;
	
	// Create the fill styles we'll be using
	red_fill = newSWFSolidFillStyle(0xf0, 0x00, 0x00, 0x99);
	dark_blue_fill = newSWFSolidFillStyle(0x00, 0x00, 0x90, 0x99);
	green_fill = newSWFSolidFillStyle(0x00, 0xcc, 0x00, 0x99);
	
	// *** Create the Play button ***
	
	// Create a shape to be used in the play button for its "UP" state
	play_shape_up = newSWFShape();
	// Use the dark blue fill
	SWFShape_setRightFillStyle(play_shape_up, green_fill);  
	SWFShape_setLine(play_shape_up, 1, 0x00, 0x00, 0x00, 0xff);
	SWFShape_movePenTo(play_shape_up, swfInfo->ControlsX-25, swfInfo->ControlsY);
	SWFShape_drawLine(play_shape_up,  20,  15);
	SWFShape_drawLine(play_shape_up, -20,  15);
	SWFShape_drawLine(play_shape_up,   0, -30);
	
	// Create a shape to be used in the play button for its "DOWN" state
	play_shape_down = newSWFShape();
	// Use the green fill
	SWFShape_setRightFillStyle(play_shape_down, dark_blue_fill);  
	SWFShape_setLine(play_shape_down, 1, 0x00, 0x00, 0x00, 0xff);
	SWFShape_movePenTo(play_shape_down, swfInfo->ControlsX-25, swfInfo->ControlsY);
	SWFShape_drawLine(play_shape_down,  20,  15);
	SWFShape_drawLine(play_shape_down, -20,  15);
	SWFShape_drawLine(play_shape_down,   0, -30);
	
	// Create an empty button object we can use
	play_button = newSWFButton();
	
	// Add the shapes to the button for its various states
	play_record_up = SWFButton_addCharacter(play_button, 
		(SWFCharacter) play_shape_up, 
		SWFBUTTON_UP|SWFBUTTON_HIT|SWFBUTTON_OVER);
	play_record_down = SWFButton_addCharacter(play_button, 
		(SWFCharacter) play_shape_down, SWFBUTTON_DOWN);
	
	// Add the Play action to the play button 
	play_action = newSWFAction("_root.play();");
	SWFButton_addAction(play_button, play_action, SWFBUTTON_MOUSEUP);
	
	// *** Create the Stop button ***
	
	// Create a shape to be used in the stop button for its "UP" state
	stop_shape_up = newSWFShape();
		// Use the green fill
	SWFShape_setRightFillStyle(stop_shape_up, red_fill);  
	SWFShape_setLine(stop_shape_up, 1, 0x00, 0x00, 0x00, 0xff);
	SWFShape_movePenTo(stop_shape_up, 
		swfInfo->ControlsX , swfInfo->ControlsY + 2.5);
	SWFShape_drawLine(stop_shape_up,  25,  0);
	SWFShape_drawLine(stop_shape_up,   0, 25);
	SWFShape_drawLine(stop_shape_up, -25,  0);
	SWFShape_drawLine(stop_shape_up,  0, -25);
	
	// Create a shape to be used in the stop button for its "DOWN" state
	stop_shape_down = newSWFShape();
	// Use the dark blue fill
	SWFShape_setRightFillStyle(stop_shape_down, dark_blue_fill);  
	SWFShape_setLine(stop_shape_down, 1, 0x00, 0x00, 0x00, 0xff);
	SWFShape_movePenTo(stop_shape_down, 
		swfInfo->ControlsX , swfInfo->ControlsY + 2.5);
	SWFShape_drawLine(stop_shape_down,  25,   0);
	SWFShape_drawLine(stop_shape_down,   0,  25);
	SWFShape_drawLine(stop_shape_down, -25,   0);
	SWFShape_drawLine(stop_shape_down,   0, -25);
	
	// Create an empty button object we can use
	stop_button = newSWFButton();
	
	// Add the shapes to the button for its various states
	stop_record_up = SWFButton_addCharacter(stop_button, 
		(SWFCharacter) stop_shape_up, 
		SWFBUTTON_UP | SWFBUTTON_HIT | SWFBUTTON_OVER);
	stop_record_down = SWFButton_addCharacter(stop_button, 
		(SWFCharacter) stop_shape_down, SWFBUTTON_DOWN);
	
	// Add the Stop action to the stop button
	stop_action = newSWFAction("_root.stop();");
	SWFButton_addAction(stop_button, stop_action, SWFBUTTON_MOUSEUP);
	
	// *** Create the movie clip container for the buttons ***
	
	// Embed the buttons in a movie clip
	//movie_clip = newSWFMovieClip();
	playd = SWFMovie_add(swfInfo->m, (SWFBlock) play_button);
	stopd = SWFMovie_add(swfInfo->m, (SWFBlock) stop_button);
	addToDisplayList( playd );
	addToDisplayList( stopd );

    // Advance the movie clip one frame, else it doesn't get displayed
    //SWFMovieClip_nextFrame(movie_clip);

    // Add the movie clip to the main movie
    //buttons_display_item = SWFMovie_add(swfInfo->m, movie_clip);
	//addToDisplayList( buttons_display_item );

    // Set the movie clip to be shown higher 
	// in the display stack than the main movie
    //SWFDisplayItem_setDepth(buttons_display_item, 100);
	
}
void InvestigationScene::questionStart() {
    
    inputLocked = true;
        
    currentFilter.where = NULL;
    currentFilter.who = NULL;
    
    actionButton->setEnabled(false);
    actionButton->setVisible(false);
    
    cancelQuestionButton->setEnabled(true);
    cancelQuestionButton->setVisible(true);
    
    removeQuestionElements();
    
    std::string question = "Select a question to ask ";
    question.append(activeCharacter->name);
    
    questionLabel->setText(question.c_str());
    questionLabel->setVisible(true);
    
    bkgQuestion->setVisible(true);
    
    Button *button = new Button("Who was in the...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 200));
    button->setTag(101);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button("Where was...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 260));
    button->setTag(102);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button("Anything strange...", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 320));
    button->setTag(103);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
    
    button = new Button("You are the murderer!", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    button->setZOrder(504);
    button->setAnchorPoint(pointMake(0.5, 0.5));
    button->setPosition(pointMake(400, 380));
    button->setTag(104);
    button->setHandler(this);
    
    addToDisplayList(button);
    questionElements.push_back(button);
}
void InvestigationScene::setupScene() {
    
    std::vector<Point> positions;
    positions.push_back(pointMake(32, 48));
    positions.push_back(pointMake(34, 48));
    positions.push_back(pointMake(36, 48));
    positions.push_back(pointMake(38, 48));
    positions.push_back(pointMake(40, 49));
    positions.push_back(pointMake(40, 51));
    positions.push_back(pointMake(40, 53));
    positions.push_back(pointMake(30, 49));
    positions.push_back(pointMake(30, 51));
    positions.push_back(pointMake(32, 52));
    
    const char *fontFile = "res/AveriaSerif-Regular.ttf";
    
    font = al_load_font(fontFile, 18, 0);
    if (!font) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", fontFile);
    }
    
    fontBig = al_load_font(fontFile, 26, 0);
    if (!fontBig) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", fontFile);
    }
    
    searchSound = al_load_sample("res/search.wav");
    if (!searchSound) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", "res/search.wav");
    }
    
    clickSound = al_load_sample("res/click.wav");
    if (!clickSound) {
        Director::getInstance()->abortWithMessage("%s not found or failed to load\n", "res/click.wav");
    }
    
    std::vector<TilemapLayer *> layers = TilemapLayer::parseTMXFile("res/mansion.tmx");
    std::vector<TilemapLayer *>::iterator it;
    
    TilemapLayer *firstLayer = layers[0];
    
    camera = new Camera(800, 600, firstLayer->getBoundsSize().width, firstLayer->getBoundsSize().height);
    
    for (it = layers.begin(); it < layers.end(); ++it) {
        
        TilemapLayer *layer = (TilemapLayer *) *it;
        layer->setCamera(camera);
        addToDisplayList(layer);
        
        if (layer->isCollision()) {
            collision = layer;
        }
    }
            
    playerSprite = new Spritesheet("res/professor_walk_cycle_no_hat.png", 64, 64);
    playerSprite->setTag(PLAYER_SPRITE_TAG);
    playerSprite->setCamera(camera);
    playerSprite->setPosition(pointMake(35 * 32, 50 * 32));
    playerSprite->setAnchorPoint(pointMake(0.5, 0.9));
    playerSprite->setAutoZOrder(true);
    addToDisplayList(playerSprite);
    
    mysterySeed = 0;
    
    do {
        
        mysteryTime = 0;
        mysterySeed = time(0);
        
        mystery = new Mystery("res/mansion.xml", mysterySeed, collision->getData(), collision->getSize().width, collision->getSize().height);
        
        while (!mystery->ended && mysteryTime < MAX_MYSTERY_DURATION) {
            mystery->step();
            mysteryTime++;
        }
        
        if (!mystery->ended) {
            delete mystery;
            mystery = NULL;
        }
        
    } while (mystery == NULL);
                    
    printf("Case seed: %d Total duration: %ld %s\n", mysterySeed, mysteryTime, timeToString(mysteryTime, true).c_str());
    
    std::vector<Character *> characters = mystery->getCharacters();
    std::vector<Character *>::iterator itChars;
    
    int i = 0;
    
    for (itChars = characters.begin(); itChars < characters.end(); ++itChars) {
        
        Character *character = (Character *) *itChars;
        
        int frame = i * 2;
        
        if (!character->dead) {
            int idx = rand() % positions.size();
            Point pos = positions[idx];
            
            character->position = pos;
            
            positions.erase(positions.begin() + idx);
        } else {
            frame++;
        }
        
        Spritesheet *sprite = new Spritesheet("res/characters.png", 64, 64);
        sprite->setTag(character->tag);
        sprite->setCamera(camera);
        sprite->setAnchorPoint(pointMake(0.5, 0.9));
        sprite->setAutoZOrder(true);
        sprite->setFrame(frame);
        
        Rect tileRect = collision->getTileRect(character->position.x, character->position.y);
        sprite->setPosition(rectMidPoint(tileRect));
        
        addToDisplayList(sprite);        
        
        i++;
    }
    
    std::vector<POI *>::iterator itWeapons;
    
    i = 0;
    
    for (itWeapons = mystery->weapons.begin(); itWeapons < mystery->weapons.end(); ++itWeapons) {
        
        POI *weapon = (POI *) *itWeapons;
        
        Spritesheet *sprite = new Spritesheet("res/weapons.png", 32, 32);
        sprite->setTag(i + 20);
        sprite->setFrame(i);
        sprite->setCamera(camera);
        sprite->setAnchorPoint(pointMake(0.5, 0.5));
        sprite->setZOrder(400);
        
        Rect tileRect = collision->getTileRect(weapon->position.x, weapon->position.y);
        sprite->setPosition(rectMidPoint(tileRect));
        
        addToDisplayList(sprite);
        
        i++;
    }
    
    actionButton = new Button("action", font, BTN_TXT_COLOR, "res/btn_action.png", "res/btn_action_pressed.png");
    actionButton->setZOrder(500);
    actionButton->setAnchorPoint(pointMake(0.5, 1));
    actionButton->setPosition(pointMake(400, 400));
    actionButton->setCamera(camera);
    actionButton->setHandler(this);
    
    addToDisplayList(actionButton);
    
    Spritesheet *bkgRoomLabel = new Spritesheet("res/bkg_room_name.png");
    bkgRoomLabel->setAnchorPoint(pointMake(0.5, 0.5));
    bkgRoomLabel->setPosition(pointMake(400, 40));
    bkgRoomLabel->setZOrder(501);
    
    addToDisplayList(bkgRoomLabel);
    
    currentRoomLabel = new Label("room", font, al_map_rgb(0, 0, 0));
    currentRoomLabel->setAnchorPoint(pointMake(0.5, 0.5));
    currentRoomLabel->setPosition(bkgRoomLabel->getPosition());
    currentRoomLabel->setZOrder(502);
    
    addToDisplayList(currentRoomLabel);
    
    Spritesheet *bkgWeaponLabel = new Spritesheet("res/bkg_room_name.png");
    bkgWeaponLabel->setAnchorPoint(pointMake(0.5, 0.5));
    bkgWeaponLabel->setPosition(pointMake(720, 40));
    bkgWeaponLabel->setZOrder(501);
    
    addToDisplayList(bkgWeaponLabel);
    
    crimeWeaponLabel = new Label("No weapon", font, al_map_rgb(0, 0, 0));
    crimeWeaponLabel->setAnchorPoint(pointMake(0.5, 0.5));
    crimeWeaponLabel->setPosition(bkgWeaponLabel->getPosition());
    crimeWeaponLabel->setZOrder(502);
    
    addToDisplayList(crimeWeaponLabel);
    
    Spritesheet *bkgAccusationLabel = new Spritesheet("res/bkg_room_name.png");
    bkgAccusationLabel->setAnchorPoint(pointMake(0.5, 0.5));
    bkgAccusationLabel->setPosition(pointMake(80, 40));
    bkgAccusationLabel->setZOrder(501);
    
    addToDisplayList(bkgAccusationLabel);
    
    char buf[100];
    sprintf(buf, "%d accusations left", MAX_ACCUSATIONS);
    
    accusationsLabel = new Label(buf, font, al_map_rgb(0, 0, 0), 120);
    accusationsLabel->setAnchorPoint(pointMake(0.5, 0.5));
    accusationsLabel->setPosition(bkgAccusationLabel->getPosition());
    accusationsLabel->setZOrder(502);
    
    addToDisplayList(accusationsLabel);
    
    bkgQuestion = new Spritesheet("res/bkg_question.png");
    bkgQuestion->setAnchorPoint(pointMake(0.5, 0.5));
    bkgQuestion->setPosition(pointMake(400, 300));
    bkgQuestion->setZOrder(503);
    bkgQuestion->setVisible(false);
        
    addToDisplayList(bkgQuestion);
    
    questionLabel = new Label("question", font, al_map_rgb(0, 0, 0), 350);
    questionLabel->setAnchorPoint(pointMake(0.5, 0.5));
    questionLabel->setPosition(pointMake(400, 120));
    questionLabel->setZOrder(504);
    questionLabel->setVisible(false);
    
    addToDisplayList(questionLabel);
    
    whenLabel = new Label("00:00 and 00:15", fontBig, al_map_rgb(0, 0, 0));
    whenLabel->setAnchorPoint(pointMake(0.5, 0.5));
    whenLabel->setPosition(pointMake(400, 300));
    whenLabel->setZOrder(504);
    whenLabel->setVisible(false);
    
    addToDisplayList(whenLabel);
    
    askQuestionButton = new Button("Ask", font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png");
    askQuestionButton->setZOrder(504);
    askQuestionButton->setAnchorPoint(pointMake(0.5, 0.5));
    askQuestionButton->setPosition(pointMake(480, 490));
    askQuestionButton->setHandler(this);
    askQuestionButton->setVisible(false);
    askQuestionButton->setEnabled(false);
    
    addToDisplayList(askQuestionButton);
    
    cancelQuestionButton = new Button("Cancel", font, BTN_TXT_COLOR, "res/btn_med.png", "res/btn_med_pressed.png");
    cancelQuestionButton->setZOrder(504);
    cancelQuestionButton->setAnchorPoint(pointMake(0.5, 0.5));
    cancelQuestionButton->setPosition(pointMake(300, 490));
    cancelQuestionButton->setHandler(this);
    cancelQuestionButton->setVisible(false);
    cancelQuestionButton->setEnabled(false);
    
    addToDisplayList(cancelQuestionButton);
    
    bkgSpeech = new Spritesheet("res/speech.png");
    bkgSpeech->setAnchorPoint(pointMake(0.35, 1));
    bkgSpeech->setCamera(camera);
    bkgSpeech->setZOrder(503);
    bkgSpeech->setVisible(false);
    
    addToDisplayList(bkgSpeech);
    
    speechLabel = new Label("speech", font, al_map_rgb(0, 0, 0), 280);
    speechLabel->setAnchorPoint(pointMake(0.5, 0.5));
    speechLabel->setCamera(camera);
    speechLabel->setZOrder(504);
    speechLabel->setVisible(false);
    
    addToDisplayList(speechLabel);
    
    speechCountLabel = new Label("1/1", font, al_map_rgb(0, 0, 0));
    speechCountLabel->setAnchorPoint(pointMake(1, 0.5));
    speechCountLabel->setCamera(camera);
    speechCountLabel->setZOrder(504);
    speechCountLabel->setVisible(false);
    
    addToDisplayList(speechCountLabel);
    
    speechButton = new Button(bkgSpeech->getFrameSize());
    speechButton->setAnchorPoint(bkgSpeech->getAnchorPoint());
    speechButton->setCamera(camera);
    speechButton->setZOrder(504);
    speechButton->setEnabled(false);
    speechButton->setHandler(this);
    
    addToDisplayList(speechButton);
    
    camera->setCenter(playerSprite->getPosition());
    
    activeCharacter = NULL;
    activePOI = NULL;
    currentRoom = NULL;
    crimeWeapon = NULL;
    
    accusationsLeft = MAX_ACCUSATIONS;
    questionsAsked = 0;
    
    moving = pointMake(0, 0);
    moveDir = 0;
    curFrame = 0;
    
    endScene = false;
    debug = false;
    
    currentFilter.timeStart = 0;
    currentFilter.timeEnd = QUESTION_INTERVAL;
    
    std::string msg;
    msg.append(mystery->victim->name);
    msg.append("'s body was found around ");
    msg.append(timeToString(mystery->corpseFoundTime + START_TIME, false));
    msg.append(" in the ");
    msg.append(mystery->corpseFoundRoom->name);
    msg.append(".");
    
    ModalDialog *dialog = new ModalDialog(msg.c_str(), font, "OK", NULL);
    dialog->setHandler(this);
    dialog->showInScene(this, 1000);
    
    music = al_load_audio_stream("res/mystery.ogg", 4, 2048);
    al_set_audio_stream_playmode(music, ALLEGRO_PLAYMODE_LOOP);
    al_attach_audio_stream_to_mixer(music, al_get_default_mixer());
    
    inDialogue = false;
    inputLocked = true;
    
    investigationStartTime = time(0);
}