// -----------------------------------------------------------
// slide1.c - giant TTG logo + credits scroller
//   effects: gold wash on the logo, smooth pixel scroll,
//   pulsing title, raster color gradient behind the scroller
// -----------------------------------------------------------
#include "defs.h"
#include "common.h"
#include "slides.h"

// ---- data ----

// 8x8 bitmaps of the giant letters (one byte per row, MSB = left pixel)
static const char bigfont[3][8] = {
	// T
	{ 0xff, 0xff, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c },
	// T
	{ 0xff, 0xff, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c },
	// G
	{ 0x7e, 0xc3, 0xc0, 0xc0, 0xcf, 0xc3, 0xc3, 0x7e }
};

static const char letter_off[3] = { 0, 10, 20 };  // column offset of each letter
                                                  //   (8 wide + 2 gap)

static const char gradtbl[10] = {    // scroller backdrop: blue ramp, cyan peak
	0x06, 0x06, 0x0e, 0x0e, 0x03, 0x03, 0x0e, 0x0e, 0x06, 0x06
};

static const char scrolltext[] =
	"mr.zero - tasnadi zsolt / mr.one - tari balazs / "
	"mr.two - timar zoltan / mr.three - mezo bela / ";

// ---- variables ----
static char xscroll;
static char scrollidx;

// ---- draw the giant TTG letters from 8x8 bitmaps ----
static void draw_logo(void)
{
	for (char l = 0; l < 3; l++)
	{
		char *sp = SCREEN + BIGROW * 40 + BIGCOL + letter_off[l];
		char *cp = COLRAM + BIGROW * 40 + BIGCOL + letter_off[l];
		for (char r = 0; r < 8; r++)
		{
			char bits = bigfont[l][r];
			for (char b = 0; b < 8; b++)     // leftmost pixel first
			{
				if (bits & 0x80)
				{
					sp[b] = 0xa0;            // inverse space = solid block
					cp[b] = VCOL_YELLOW;
				}
				bits <<= 1;
			}
			sp += 40;                        // advance one screen row
			cp += 40;
		}
	}
}

// ---- shift the scroller row one char left, feed in the next char ----
static void shift_row(void)
{
	for (char x = 0; x < 39; x++)
		SCREEN[SCROLLROW * 40 + x] = SCREEN[SCROLLROW * 40 + 1 + x];
	SCREEN[SCROLLROW * 40 + 39] = scrolltext[scrollidx];
	scrollidx++;
	if (!scrolltext[scrollidx])
		scrollidx = 0;
}

// ---- color wash: gold gradient running across the logo columns ----
static void do_wash(void)
{
	for (char x = 0; x < 28; x++)            // 28 logo columns
	{
		char c = washtbl[(x + washphase) & 15];
		COLRAM[(BIGROW + 0) * 40 + BIGCOL + x] = c;
		COLRAM[(BIGROW + 1) * 40 + BIGCOL + x] = c;
		COLRAM[(BIGROW + 2) * 40 + BIGCOL + x] = c;
		COLRAM[(BIGROW + 3) * 40 + BIGCOL + x] = c;
		COLRAM[(BIGROW + 4) * 40 + BIGCOL + x] = c;
		COLRAM[(BIGROW + 5) * 40 + BIGCOL + x] = c;
		COLRAM[(BIGROW + 6) * 40 + BIGCOL + x] = c;
		COLRAM[(BIGROW + 7) * 40 + BIGCOL + x] = c;
	}
}

// ---- pulsing title: grey-white ramp, one step per 8 frames ----
static void do_pulse(void)
{
	char c = pulsetbl[(framectr >> 3) & 7];
	for (char x = 0; x < 14; x++)            // "teletype games" = 14 chars
		COLRAM[TITLE_POS + x] = c;
}

void s1_init(void)
{
	clear_screen();
	draw_logo();

	print_text(12, 13, VCOL_WHITE,    "teletype games");
	print_text(17,  9, VCOL_LT_GREEN, "www.teletypegames.org");
	print_text(19, 14, VCOL_LT_GREY,  "szeged, 2026");

	// scroller row color: white, so it reads on the blue gradient
	for (char x = 0; x < 40; x++)
		COLRAM[SCROLLROW * 40 + x] = VCOL_WHITE;

	xscroll = 6;                             // multiple of SCROLL_STEP -> clean 4-frame cycle
	scrollidx = 0;
	washphase = 0;
}

void s1_update(void)
{
	// switch on fine scroll + 38-column mode for the scroller row only
	while (vic.raster != RAS_SCRTOP)
		;
	vic.ctrl2 = xscroll;                     // bits 0-2 = x scroll, bit 3 = 0 -> 38 columns

	// blue raster gradient behind the scroller: one background
	// color per line, chasing the beam through lines 161-170
	for (char i = 0; i < 10; i++)
	{
		char c = gradtbl[i];
		char line = RAS_SCRTOP + 1 + i;
		while (vic.raster != line)
			;
		vic.color_back = c;
	}

	while (vic.raster != RAS_SCRBOT)
		;
	vic.ctrl2 = 0xc8;                        // back to default: 40 columns, no scroll
	vic.color_back = VCOL_BLACK;             // gradient off below the scroller row

	// beam is in the lower border: do all updates now, invisibly
	while (vic.raster != RAS_BOTTOM)
		;

	framectr++;

	// smooth scroll: move SCROLL_STEP pixels, shift chars on wrap
	if (xscroll >= SCROLL_STEP)
		xscroll -= SCROLL_STEP;
	else
	{
		xscroll += 8 - SCROLL_STEP;          // wrap
		shift_row();
	}

	if (!(framectr & 1))                     // wash moves one column every 2nd frame
		washphase++;

	do_wash();
	do_pulse();
}
