- [NEW] Mòdul zx_tape, encara no carrega correctament les cintes. - [CHG] Gestió completa del só pasada a la ULA, i de la pantalla a zxscreen
85 lines
2.6 KiB
C++
85 lines
2.6 KiB
C++
#include "zx_screen.h"
|
|
#include "z80.h"
|
|
#include "zx_ula.h"
|
|
#include <SDL2/SDL.h>
|
|
|
|
namespace zxscreen
|
|
{
|
|
uint32_t palette[16] = {
|
|
0x000000, 0x000080, 0x800000, 0x800080, 0x008000, 0x008080, 0x808000, 0x808080,
|
|
0x000000, 0x0000FF, 0xFF0000, 0xFF00FF, 0x00FF00, 0x00FFFF, 0xFFFF00, 0xFFFFFF
|
|
};
|
|
SDL_Window *win = nullptr;
|
|
SDL_Renderer *ren = nullptr;
|
|
SDL_Texture *tex = nullptr;
|
|
|
|
uint32_t t_screen = 0;
|
|
uint8_t t_flash = 0;
|
|
bool flash = false;
|
|
|
|
void show()
|
|
{
|
|
if (win) return;
|
|
win = SDL_CreateWindow("ZX Spectrum Screen", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 352, 288, SDL_WINDOW_RESIZABLE);
|
|
ren = SDL_CreateRenderer(win, -1, 0);
|
|
tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 352, 288);
|
|
refresh(0);
|
|
}
|
|
|
|
void refresh(const uint8_t dt, const bool force_refresh)
|
|
{
|
|
t_screen += dt;
|
|
if (t_screen>=69888) {
|
|
t_flash++;
|
|
if (t_flash==16) { t_flash=0; flash = !flash; }
|
|
t_screen=0;
|
|
} else if (!force_refresh) return;
|
|
|
|
const uint8_t* memory = z80::getMem();
|
|
const uint8_t border_color = zx_ula::get_border_color();
|
|
//memory+=0x4000;
|
|
|
|
Uint32* pixels;
|
|
int pitch;
|
|
SDL_LockTexture(tex, NULL, (void**)&pixels, &pitch);
|
|
|
|
// Upper border
|
|
for (int i=0; i<352*48;++i) *(pixels++) = palette[border_color];
|
|
|
|
// scanlines
|
|
for (uint8_t y=0; y<192; ++y)
|
|
{
|
|
// Left border
|
|
for (int j=0;j<48;++j) *(pixels++) = palette[border_color];
|
|
|
|
// Actual screen
|
|
for (uint8_t x=0;x<32;++x)
|
|
{
|
|
uint8_t color = memory[0x5800 + x + (y>>3)*32];
|
|
|
|
uint16_t address = 0x4000 | (x&0x1f) | ((y&0x7)<<8) | ((y&0x38)<<2) | ((y&0xc0)<<5);
|
|
uint8_t block = memory[address];
|
|
uint8_t c1 = color&0x7, c2 = (color>>3)&0x7;
|
|
if ((color&0x80) && flash) { c1=c2; c2=color&0x7; }
|
|
for (int i=0;i<8;++i)
|
|
{
|
|
*(pixels++)=(block&0x80) ? palette[c1] : palette[c2];
|
|
block = block<<1;
|
|
}
|
|
}
|
|
|
|
// Right border
|
|
for (int j=0;j<48;++j) *(pixels++) = palette[border_color];
|
|
}
|
|
|
|
// Lower border
|
|
for (int i=0; i<352*48;++i) *(pixels++)=palette[border_color];
|
|
|
|
SDL_UnlockTexture(tex);
|
|
SDL_RenderCopy(ren, tex, NULL, NULL);
|
|
SDL_RenderPresent(ren);
|
|
|
|
if (t_screen==0) z80::interrupt();
|
|
}
|
|
}
|