163 lines
4.2 KiB
C
163 lines
4.2 KiB
C
#include<inttypes.h>
|
|
#include<stdbool.h>
|
|
#include<stdio.h>
|
|
#include"gb.h"
|
|
#include"ppu.h"
|
|
|
|
#define print(x,y,str) tigrPrint(gb->ppu->info,tfont,x,y,tigrRGB(0xdd,0x66,0x77),str);
|
|
#define bit(x,n) ( ((x) & 1<<(n)) >> (n) )
|
|
#define bittest(x,y,n) (bit((x),(n))|bit((y),(n))<<1)
|
|
|
|
static uint32_t palette[4]={0x00ffffff,0x00389048,0x00284028,0x000000};
|
|
|
|
uint32_t ppu_openwindow(Ppu*ppu,uint8_t*str)
|
|
{
|
|
if(!ppu)
|
|
{
|
|
fprintf(stderr,"error: cannot open window with NULL Ppu\n");
|
|
}
|
|
ppu->info=tigrWindow(160,144,"memory",0);
|
|
ppu->screen=tigrWindow(160,144,(char*)str,0);
|
|
if(ppu->screen)ppu->pixels.t=ppu->screen->pix;
|
|
return ppu->screen==NULL||ppu->info==NULL;
|
|
}
|
|
|
|
void ppu_updatejoypad(Ppu*ppu,uint8_t*ram)
|
|
{
|
|
static uint8_t jp=0;
|
|
//R L U D
|
|
jp =(tigrKeyHeld(ppu->screen,TK_RIGHT)!=0);
|
|
jp|=(tigrKeyHeld(ppu->screen,TK_LEFT )!=0)<<1;
|
|
jp|=(tigrKeyHeld(ppu->screen,TK_UP )!=0)<<2;
|
|
jp|=(tigrKeyHeld(ppu->screen,TK_DOWN )!=0)<<3;
|
|
if(ram[0xff00]==0x20)ram[0xff00]=jp;
|
|
|
|
//A B SEL START
|
|
jp =(tigrKeyHeld(ppu->screen,'Z')!=0);
|
|
jp|=(tigrKeyHeld(ppu->screen,'X')!=0)<<1;
|
|
jp|=(tigrKeyHeld(ppu->screen,'A')!=0)<<2;//sl
|
|
jp|=(tigrKeyHeld(ppu->screen,'S')!=0)<<3;//cpu
|
|
if(ram[0xff00]==0x10)ram[0xff00]=jp;
|
|
// fprintf(stderr,"joyp (0xff00):%.2xh\n",jp);
|
|
}
|
|
|
|
void ppu_drawtile(Ppu*ppu,uint8_t x,uint8_t y,uint16_t o,uint16_t t,uint8_t *ram)
|
|
{
|
|
for(int j=0;j<16;j+=2)//bitplane
|
|
for(int i=0;i<8;i++)//bit
|
|
ppu->pixels.i[(j/2+y)*160+(i+x)]=palette[bittest(ram[o+j+t*16],ram[o+1+j+t*16],7-i)];
|
|
}
|
|
|
|
uint32_t ppu_updatewindow(struct Gb*gb,uint8_t*ram)
|
|
{
|
|
static bool tilemap=false;
|
|
static uint32_t delay=0;
|
|
if(!gb->ppu->screen||!gb->ppu->info)return 1;
|
|
delay++;
|
|
if(delay%400!=0)return 0;
|
|
|
|
if(!tigrClosed(gb->ppu->screen) && !tigrClosed(gb->ppu->info))
|
|
{
|
|
if(tigrKeyHeld(gb->ppu->screen,TK_ESCAPE)||tigrKeyHeld(gb->ppu->info,TK_ESCAPE))
|
|
return -1;
|
|
if(tigrKeyHeld(gb->ppu->screen,'Q')||tigrKeyHeld(gb->ppu->info,'Q'))
|
|
return -1;
|
|
|
|
// Draw graphical/main screen
|
|
{
|
|
tigrClear(gb->ppu->screen,tigrRGB(255,255,255));
|
|
if(tigrKeyDown(gb->ppu->screen,'P'))gb->paused=!gb->paused;
|
|
if(tigrKeyDown(gb->ppu->screen,'L'))
|
|
{
|
|
gb->log=!gb->log;
|
|
if(!gb->log)
|
|
cpu_log_clear();
|
|
}
|
|
if(tigrKeyDown(gb->ppu->screen,'M'))gb->ppu->mode=!gb->ppu->mode;
|
|
if(tigrKeyDown(gb->ppu->screen,TK_SPACE))tilemap=!tilemap;
|
|
|
|
//Draw all tiles
|
|
if(tilemap)//LCD DISPLAY ON
|
|
{
|
|
//uint16_t tilemap_select=0x9800;
|
|
//if(ram[0xff40]&0x40)tilemap_select=0x9c00;
|
|
for(int j=0;j<18;j++)//tile map veritcal
|
|
for(int i=0;i<20;i++)//tile map horizontal
|
|
ppu_drawtile(gb->ppu,i*8,j*8,0x8000,ram[0x9800+(j*0x20+i)],ram);
|
|
|
|
uint16_t oam_offs=0xfe00;//should be 0xfe00
|
|
for(int i=0;i<40;i+=4)//OAM sprites
|
|
if(ram[oam_offs+i*4]>=8&&ram[oam_offs+i*4+1]>=16)
|
|
ppu_drawtile(gb->ppu,ram[oam_offs+i*4]-8,ram[oam_offs+i*4+1]-16,0x8000,ram[oam_offs+i*4+2],ram);
|
|
}
|
|
else
|
|
// for(int i=0;i<256+128;i++)
|
|
for(int i=0;i<256;i++)
|
|
ppu_drawtile(gb->ppu,i%16*8,(i/16)*8,0x8000,i,ram);
|
|
}
|
|
|
|
// Draw information screen
|
|
{
|
|
tigrClear(gb->ppu->info,tigrRGB(0x22,0x22,0x22));
|
|
|
|
// Print mode name
|
|
static char str[128];
|
|
sprintf(str,"%s",(gb->ppu->mode==M_MEM)?("memory"):("disasm"));
|
|
print(0,0,str);
|
|
|
|
switch(gb->ppu->mode)
|
|
{
|
|
|
|
default:
|
|
case M_MEM:
|
|
{
|
|
auto uint16_t ad=0xff46;
|
|
auto uint8_t i=0;
|
|
|
|
while(i<9)
|
|
{
|
|
sprintf(str,"%.4x: %.2x %.2x %.2x %.2x %.2x %.2x",ad+i*6,ram[ad+i*6],ram[ad+i*6+1],ram[ad+i*6+2],ram[ad+i*6+3],ram[ad+i*6+4],ram[ad+i*6+5]);
|
|
print(0,12+i*12+1,str);
|
|
++i;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Can we capture from cpu_decexec at certain intervals?
|
|
// (with a buffer)
|
|
case M_DASM:
|
|
{
|
|
static char str[128];
|
|
sprintf(str,"%.4x:%s",gb->cpu->pc,cpu_log());
|
|
print(0,12,str);
|
|
|
|
sprintf(str,"log:%s",(gb->log)?"on":"off");
|
|
print(0,121,str);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
// All modes:
|
|
sprintf(str,"PC: %.4x%s",gb->cpu->pc,gb->paused?" [paused]":"");
|
|
print(0,133,str);
|
|
|
|
}
|
|
|
|
tigrUpdate(gb->ppu->info);
|
|
tigrUpdate(gb->ppu->screen);
|
|
}
|
|
else
|
|
return -1; //0xffffffff
|
|
return 0;
|
|
}
|
|
|
|
uint32_t ppu_closewindow(Ppu*ppu)
|
|
{
|
|
if(!ppu->screen)return 1;
|
|
tigrFree(ppu->screen);
|
|
if(!ppu->info)return 1;
|
|
tigrFree(ppu->info);
|
|
return 0;
|
|
}
|