Пример #1
0
void Image::draw()
{
    printf("Image::draw called\n");
    for (int i = 0; i < m_height; i++)
        drawScanline(i);
	glFlush();
}
Пример #2
0
void updateGraphicsTest(struct gameboy * gameboy)
{
	//fill a frame buffer with some simple pixel data and see if it draws correctly
	setLCDStatus(gameboy);
	uint8_t previousMode = getCurrentMode(gameboy);
	requestAnyNewModeInterrupts(gameboy, previousMode);
	if (isLCDEnabled(gameboy)){
		gameboy->screen.scanlineCounter += gameboy->cpu.previousInstruction.cycles;
	}
	else {
		return;
	}
	
	if (gameboy->screen.scanlineCounter >= SCANLINE_CYCLE_TIME){
		gameboy->screen.currentScanline++;
		gameboy->screen.scanlineCounter = 0;
		if (gameboy->screen.currentScanline == Y){
			requestInterrupt(gameboy, int_vblank);
			//printf("start vblank\n");
		}
		else if (gameboy->screen.currentScanline > (Y + NO_OF_INVISIBLE_SCANLINES)){
			gameboy->screen.currentScanline = 0;
			//printf("resetting scanline\n");
		}
		else if (gameboy->screen.currentScanline < Y){
//			printf("drawing scanline %d\n", gameboy->screen.currentScanline);
			drawScanline(gameboy);
		}
		else {
			//printf("In vblank\n");
		}
	}
	
}
void Image::drawScanlines(int yMin, int yMax)
{
	for (int i = yMin; i < yMax; i++)
	{
		drawScanline(i);
	}	
}
Пример #4
0
void
Canvas::drawTriangle(const Vertex &v1, const Vertex &v2, const Vertex &v3, const Texture *texture) {
    // sort a b c by y, top to bottom
    const Vertex *a = &v1;
    const Vertex *b = &v2;
    const Vertex *c = &v3;
    if (a->position.y > b->position.y) {
        std::swap(a, b);
    }
    if (b->position.y > c->position.y) {
        std::swap(b, c);
    }
    if (a->position.y > b->position.y) {
        std::swap(a, b);
    }
    
    float middleFactor = (float)(b->position.y - a->position.y) / (c->position.y - a->position.y);
    Vertex middle = a->interpolate(*c, middleFactor);
    
    int startY = a->position.y;
    int endY = b->position.y;
    for (int y = startY; y <= endY; ++y) {
        float factor = 0;
        if (endY != startY) {
            factor = (float)(y - startY) / (endY - startY);
        }
        Vertex va = a->interpolate(*b, factor);
        Vertex vb = a->interpolate(middle, factor);
        drawScanline(va, vb, y, texture);
    }
    startY = b->position.y;
    endY = c->position.y;
    for (int y = startY; y <= endY; ++y) {
        float factor = 0;
        if (endY != startY) {
            factor = (float)(y - startY) / (endY - startY);
        }
        Vertex va = b->interpolate(*c, factor);
        Vertex vb = middle.interpolate(*c, factor);
        drawScanline(va, vb, y, texture);
    }
}
Пример #5
0
static void handleCurrentScanline(struct gameboy * gameboy)
{
	uint8_t currentScanline = gameboy->screen.currentScanline;
	if (currentScanline == Y){
		requestInterrupt(gameboy, int_vblank);
	}
	else if (currentScanline > (Y + NO_OF_INVISIBLE_SCANLINES)){
		gameboy->screen.currentScanline = 0; //reset
	}
	else {
		drawScanline(gameboy);
	}
}
void Image::draw()
{
    for (int i = 0; i < m_height; i++)
        drawScanline(i);
}
Пример #7
0
//update lcdstatus
INLINE void updateLCDStatus(int cycles){
    
    STAT |= 0x80;

    //lcd enabled
    if (LCDC&0x80){

        gbcpu.lcd->scanlinecyclecounter -= cycles;

        //setting modes and requesting interrupts when switching
        if(LY>=144){
            //set mode to 1
            STAT=(STAT&0xFC) | 0x1;
        }else{

            int previousmode = STAT & 0x3;
            int requestinterrupt = 0;

            if (gbcpu.lcd->scanlinecyclecounter >= 376)
            {
                //set mode to 2 (OAM-RAM search)
                STAT=(STAT&0xFC) | 0x2; 
                requestinterrupt  = STAT & 0x20;
            }
            else if(gbcpu.lcd->scanlinecyclecounter >= 204)
            {
                //set mode to 3 (Data Transfer)
                STAT=(STAT&0xFC) | 0x3;
            }
            else
            {
                //set to mode 0 (H-Blank)
                STAT&=0xFC;
                requestinterrupt  = STAT & 0x8;
            }

            //request interrupt when mode changed for the 1st time
            if (requestinterrupt && (previousmode != (STAT & 0x3)))
                interruptZ80(I_LCD_STAT);

        }

        //move to next scanline
        if (gbcpu.lcd->scanlinecyclecounter <=0)
        {
            LY+=1;
            gbcpu.lcd->scanlinecyclecounter=456;

            //starting vsync period
            if (LY==144){

                //request vblank
                interruptZ80(I_V_BLANK);

                //set mode to 1
                STAT=(STAT&0xFC) | 0x1;
                return;
            }

            if(LY <144){
               drawScanline();
            }

            LY=LY%154;

        }

        LY_LYC();

    }else{
        //set mode to 0
        STAT=(STAT&0xF8);
        //reset counter
        gbcpu.lcd->scanlinecyclecounter=456;
        //reset LY
        LY=0;
    }
}