void Image::draw() { printf("Image::draw called\n"); for (int i = 0; i < m_height; i++) drawScanline(i); glFlush(); }
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); } }
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); } }
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); }
//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; } }