示例#1
0
void DrawString(u8 *screen, const char *str, u32 x, u32 y, Color color)
{
    u32 i;
    for (i = 0; i < strlen(str); i++){
        DrawCharacter(screen, str[i], x + i * FONT_SIZE, y, color);
    }
}
示例#2
0
文件: riots.c 项目: dos1/mediator
void DrawRockets(struct Game *game, struct RocketsResources* data, struct Rocket* rockets) {
	  struct Rocket *tmp = rockets;
		while (tmp) {
			  DrawCharacter(game, tmp->character, al_map_rgb(255,255,255), 0);

				tmp=tmp->next;
		}
}
示例#3
0
void TeletextScreen::DrawStatus(void)
{
    SetForegroundColor(kTTColorWhite);
    SetBackgroundColor(kTTColorBlack);

    if (!m_teletextReader->IsTransparent())
        for (int i = 0; i < 40; ++i)
            DrawBackground(i, 0);

    DrawCharacter(1, 0, 'P', 0);
    DrawCharacter(2, 0, m_teletextReader->GetPageInput(0), 0);
    DrawCharacter(3, 0, m_teletextReader->GetPageInput(1), 0);
    DrawCharacter(4, 0, m_teletextReader->GetPageInput(2), 0);

    const TeletextSubPage *ttpage = m_teletextReader->FindSubPage();

    if (!ttpage)
    {
        QString str = QObject::tr("Page Not Available",
                                  "Requested Teletext page not available");
        for (int i = 0; (i < 30) && i < str.length(); i++)
            DrawCharacter(i+10, 0, str[i], 0);

        return;
    }

    QString str = m_teletextReader->GetPage();
    if (str.isEmpty())
        return;

    SetForegroundColor(kTTColorWhite);
    for (int x = 0; x < 11; x++)
    {
        if (m_teletextReader->IsTransparent())
            SetBackgroundColor(kTTColorTransparent);
        else
            SetBackgroundColor(kTTColorBlack);

        DrawBackground(x * 3 + 7, 0);

        if (str[x * 3] == '*')
        {
            str[x * 3] = ' ';
            SetBackgroundColor(kTTColorRed);
        }

        DrawBackground(x * 3 + 8, 0);
        DrawBackground(x * 3 + 9, 0);

        DrawCharacter(x * 3 + 7, 0, str[x * 3], 0);
        DrawCharacter(x * 3 + 8, 0, str[x * 3 + 1], 0);
        DrawCharacter(x * 3 + 9, 0, str[x * 3 + 2], 0);
    }
}
示例#4
0
文件: ponglyph.c 项目: 128keaton/ltdc
/** State - Process game */
void StateUpdateGame()
{
	u8 keyLine;

	// Flip page
	SetPage8(game.page);
	game.page = 1 - game.page;
	game.yOffset = 256 * game.page;

	// Change analglyph effect power
	keyLine = GetKeyMatrixLine(0);
	if((keyLine & KEY_1) == 0)
	{
		if(game.power3d > 0)
			game.power3d--;
		ClearScreen8(BG_COLOR);
	}
	if((keyLine & KEY_2) == 0)
	{
		if(game.power3d < 24)
			game.power3d++;
		ClearScreen8(BG_COLOR);
	}

	// Clear
	ClearLines();
	DrawBackground();

	if(game.playerNum == 1)
	{
		DrawCharacter(128-20, 8 + game.yOffset, '0' + (game.players[0].score >> 4) - ' ', COLOR8_WHITE);
		DrawCharacter(128-12, 8 + game.yOffset, '0' + (game.players[0].score & 0x0F) - ' ', COLOR8_WHITE);
		DrawCharacter(128-4,  8 + game.yOffset, '-' - ' ', COLOR8_WHITE);
		DrawCharacter(128+4,  8 + game.yOffset, '0' + (game.bestScore >> 4) - ' ', COLOR8_WHITE);
		DrawCharacter(128+12, 8 + game.yOffset, '0' + (game.bestScore & 0x0F) - ' ', COLOR8_WHITE);
	}
示例#5
0
文件: draw.cpp 项目: Normmatt/hwtests
void DrawString(u8* fb, font_s* f, const std::string& str, s16 x, s16 y, u16 w, u16 h)
{
    if (!f || !fb)
        return;

    int dx = 0, dy = 0;
    for (const char& c : str)
    {
        dx += DrawCharacter(fb, f, c, x + dx, y + dy, w, h);
        if (c == '\n') {
            dx = 0;
            dy -= f->height;
        }
    }
}
示例#6
0
void FontRasterizer::DrawFont(ID3D11DeviceContext* context, FXMVECTOR pos, float fontWidth, float fontHeight, int charsPerLine, std::string text/*, CXMMATRIX p*/)
{
	D3D11_MAPPED_SUBRESOURCE mappedData;
	HR(context->Map(VB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData));
	Vertex::NormalTexVertex* v = reinterpret_cast<Vertex::NormalTexVertex*> (mappedData.pData);

	float x = pos.m128_f32[0];
	float y = pos.m128_f32[1];
	for (int i = 0; i < text.size(); ++i)
	{
		//draw a character
		DrawCharacter(text[i], x, y, fontWidth, fontHeight, v, i);

		x += fontWidth;
		if (i % charsPerLine == charsPerLine - 1)
		{
			y -= fontHeight;
			x = pos.m128_f32[0];
		}
	}

	context->Unmap(VB, 0);

	XMMATRIX vp = XMMatrixIdentity();
	XMMATRIX proj = XMLoadFloat4x4(&m2DProj);
	XMMATRIX view = m2DCam->GetView();

	vp = vp * view * proj;

	context->IASetInputLayout(Vertex::GetNormalTexVertLayout());
	context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	mEffect->SetPerObjectParams(XMMatrixIdentity(), XMMatrixIdentity(), vp, mFontImage);

	mEffect->Draw(context, VB, IB, text.size() * 6);
}
示例#7
0
void g2LabelEdit::Render(int pX, int pY)
{
    // Ignore if not null
    if(TextBuffer == NULL)
        return;
    
    // Total offset from the far left
    int OffsetX = 0;
    
    // For each character...
    for(size_t i = ViewIndex; i < strlen(TextBuffer); i++)
    {
        // Get target character and width
        int CharWidth;
        GetTheme()->GetCharacterSize(TextBuffer[i], &CharWidth, NULL);
        
        // Stop drawing if this one or the next character is out of bounds
        if((OffsetX + CharWidth) >= Width)
            break;
        
        // Draw shadow if on
        if(Shadow)
        {
            // Get active color for shadow
            float Sr, Sg, Sb;
            GetColor(&Sr, &Sg, &Sb);
            DrawCharacter(pX + OffsetX + 1, pY + 1, 1.0f, 1.0f, Sr, Sg, Sb, 0.2f, TextBuffer[i]);
        }
        
        // Render text normally
        DrawCharacter(pX + OffsetX, pY, TextBuffer[i]);
        
        // Grow the offset
        OffsetX += CharWidth + g2LabelEdit_CharacterSpacing;
    }
    
    // Draw the blinking cursor
    if(( (GetActive() && !GetDisabled()) || CursorAlwaysVisible ) && CursorState)
    {
        // Reset offset for rendering again
        OffsetX = 0;
        
        // Go through each character attempting to render
        for(size_t i = ViewIndex; i <= strlen(TextBuffer); i++)
        {
            // Draw and stop at the cursor index
            if((int)i == CursorIndex)
            {
                DrawCharacter(pX + OffsetX - 1, pY, '|');
                break;
            }
            
            // Grow offset
            int CharWidth;
            GetTheme()->GetCharacterSize(TextBuffer[i], &CharWidth, NULL);
            OffsetX += CharWidth + g2LabelEdit_CharacterSpacing;
        }
    }
    
    // Done with rendering...
}
示例#8
0
文件: riots.c 项目: dos1/mediator
void Gamestate_Draw(struct Game *game, struct RocketsResources* data) {

	  al_set_target_bitmap(data->pixelator);

		if (!data->lost) {
			  al_draw_bitmap(data->bg, 0, 0, 0);
				//al_draw_bitmap(data->earth2, 0, 0, 0);
				//al_draw_bitmap(data->combined, 0, 0, 0);
		} else if (!data->won) {
			  al_draw_tinted_bitmap(data->bg, al_map_rgb(255, 192, 128), 0, 0, 0);
				//al_draw_tinted_bitmap(data->earth2, al_map_rgb(255, 192, 128), 0, 0, 0);
				//al_draw_tinted_bitmap(data->combined, al_map_rgb(255, 192, 128),  0, 0, 0);
		} else {
			  al_draw_bitmap(data->bg, 0, 0, 0);
				al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgba(255,255,255, 64));
		}

		if (data->won) {
			  DrawCharacter(game, data->euro, al_map_rgb(255,255,255), 0);
		}


		if ((!data->lost) && (!data->won)) {
			  DrawCharacter(game, data->cursor, al_map_rgb(255,255,255), 0);
		}

		DrawRockets(game, data, data->rockets_left);
		DrawRockets(game, data, data->rockets_right);

		if (data->lost) {
			  DrawCharacter(game, data->riot, al_map_rgb(255,255,255), 0);
		} else {
			  DrawCharacter(game, data->usa_flag, al_map_rgb(255,255,255), 1);
				DrawCharacter(game, data->ru_flag, al_map_rgb(255,255,255), 0);
				al_draw_bitmap(data->earth, 5, 50, 0);
		}


		if (data->lost) {
			  al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 2, 0, 0);
				al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 2 + 640, 0, 0);
		} else {
			  al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 3, 0, 0);
				al_draw_tinted_bitmap(data->clouds, al_map_rgba(data->zadyma, data->zadyma, data->zadyma, data->zadyma), -data->counter / 3 + 640, 0, 0);
		}


		if ((!data->lost) && (!data->won)) {
			  al_draw_filled_rectangle(78, 5, 78+164, 5+5, al_map_rgb(155, 142, 142));
				al_draw_filled_rectangle(80, 6, 80+160, 6+3, al_map_rgb(66, 55, 30));
				al_draw_filled_rectangle(80, 6, (data->counter < data->timelimit) ? (80+ 160 * (1 - (data->counter / (float)data->timelimit))) : 80, 6+3, al_map_rgb(225,182, 80));
		}

		if (data->flash) {
			  al_draw_filled_rectangle(0, 0, 320, 180, al_map_rgb(255, 255, 255));
		}

		al_set_target_backbuffer(game->display);
		al_draw_bitmap(data->pixelator, 0, 0, 0);

		if ((data->lost) && (data->hearts > 80)) {
			  ShowLevelStatistics(game);
		}

		//Gamestate_Logic(game, data);

}
void g2Controller::DrawCharacter(int DestX, int DestY, float ScaleW, float ScaleH, char Character)
{
    DrawCharacter(DestX, DestY, ScaleW, ScaleH, R, G, B, Alpha, Character);
}
void g2Controller::DrawCharacter(int DestX, int DestY, char Character)
{
    DrawCharacter(DestX, DestY, 1.0f, 1.0f, Character);
}
示例#11
0
    void Label::DrawText()
    {
        //Safety check that the font pointer is null
        if(m_Font == nullptr)
        {
            Error(false, "Unable to draw the text of the Label, the font pointer is null");
            return;
        }
        
        //Is there any text to render?
        if(m_Text.length() == 0)
        {
            return;
        }
        
        //calculate the baseline and origin for the label
        unsigned int baseline = m_Font->GetLineHeight() - m_Font->GetBaseLine();
        vec2 origin(0.0f, baseline + (m_Font->GetLineHeight() * (GetNumberOfLines() - 1)));
        int lineIndex = 0;
        
        //What justification are we dealing with
        if(m_Justification == JustifyLeft)
        {
            origin.x = 0.0f;
        }
        else if(m_Justification == JustifyCenter)
        {
            origin.x = (GetSize().x - m_LineWidth.at(lineIndex)) / 2.0f;
        }
        else if(m_Justification == JustifyRight)
        {
            origin.x = GetSize().x - m_LineWidth.at(lineIndex);
        }
        
        //Cycle through the characters in the text label
        for(unsigned int i = 0; i < m_Text.length(); i++)
        {
            //Did we reach a new line?
            if(m_Text.at(i) == '\n')
            {
                //Increment the line index
                lineIndex++;
            
                //Calculate the line's origin based on the justification
                if(m_Justification == JustifyLeft)
                {
                    origin.x = 0.0f;
                }
                else if(m_Justification == JustifyCenter)
                {
                    origin.x = (GetSize().x - m_LineWidth.at(lineIndex)) / 2.0f;
                }
                else if(m_Justification == JustifyRight)
                {
                    origin.x = GetSize().x - m_LineWidth.at(lineIndex);
                }
            
                //Set the y line origin based on the line height of the font
                origin.y -= m_Font->GetLineHeight();
                continue;
            }
            
            //Get the texture frame for the character
            TextureFrame* textureFrame = m_Font->GetTextureFrameForCharacter(m_Text.at(i));
            
            //Safety check the texture frame
            if(textureFrame != nullptr)
            {
                //Calculate the character position based on the x and y bearing
                vec2 charPosition = origin;
                charPosition.x += m_Font->GetBearingXForCharacter(m_Text.at(i));
                charPosition.y += m_Font->GetBearingYForCharacter(m_Text.at(i)) - m_Font->GetSourceFrameForCharacter(m_Text.at(i)).size.y;

                //Draw the character
                DrawCharacter(textureFrame, charPosition);
                
                //Increment the origin
                origin.x += m_Font->GetAdvanceXForCharacter(m_Text.at(i)) + GetCharacterSpacing();
            }
        }
    }
示例#12
0
int main()
{
	volatile uint32_T* systimer_clo = (volatile uint32_T*) SYSTIM_CLO; 
	volatile uint32_T* systimer_cs = (volatile uint32_T*) SYSTIM_CS;
	uint32_T* systimer_c1 = (uint32_T*) SYSTIM_C1;	
	uint32_T* irq_enable1 = (uint32_T*) IRQ_ENABLE1;
	uint32_T* gpiocntrl = (uint32_T*) GPFSEL1;
	uint32_T* gpioclear = (uint32_T*) GPCLR0;
	
	FrameBufferInfo_T* fbInfoAddr;

	uint32_T* tag_cmdline;
	
	uint32_T ii;
	uint8_T output[] = "Test Eins\n\t1 23 45";
	
	// Set gpio 16 to output
	*gpiocntrl = 1<<18;
	
	// Activate system timer c1
	*systimer_c1 = *systimer_clo + TIME_TICK;
	*systimer_cs = 0x2;
	// Enable Interrupts for system timer c1
	*irq_enable1 = 0x2; 

	// Initialise Frame Buffer
	fbInfoAddr = InitialiseFrameBuffer(XW, YW, 16);	
	
	if (fbInfoAddr == NULL)
	{	
		// signal error by lighting ACT and stopping
		*gpioclear = 1<<16;
		while(1);
	}
	
	SetGraphicsAddress(fbInfoAddr);

	SetForeColour(0xffff);
	DrawLine(0,0,XW-1,0);
	DrawLine(0,10,XW-1,10);
	clearScreen();
	
	for (ii = 0; ii < 26; ii++)
		DrawCharacter(0x41+ii, ii*8, 0);				
	for (ii = 0; ii < 26; ii++)
		DrawCharacter(0x41+ii, 4 + ii*8, 16);				

	DrawLine(0,50,XW-1,30);
	
	DrawString(output, 17, 20, YW/2);
	
	clearScreen();
	
	// Find cmdline tag
	tag_cmdline = FindTag(9);
	DrawString((uint8_T*)(tag_cmdline+2), (*tag_cmdline) - 2, 0, 0);
	
	// Enable Interrupts on ARM
	ENABLE_IRQ;

	// wait until sytick reaches 5 ms
	while(systick < 5000000/TIME_TICK);
	
	while(1) {
		uint16_T x;
		uint16_T y;
		uint16_T x_old;
		uint16_T y_old;
		uint32_T colour;
		uint32_T error;
		uint32_T message[QUEUE_DIM];
		
		if (readQueue(0, message)) {
			x = message[0] % XW;		// time in ms: 1ms is 1 px, wrapped around screen width
			y = message[1];
			if (x > x_old) {
				DrawLine(x_old, y_old, x, y);
			} else {
				clearScreen();
				SetForeColour(colour);
				colour--;
				for (ii = 0; ii < 64; ii++)
					DrawCharacter(0x41+ii, ii*8, 0);				
			}

			x_old = x;
			y_old = y;	
		}

	};
	return 1;
}
示例#13
0
void TeletextScreen::DrawLine(const uint8_t *page, uint row, int lang)
{
    bool mosaic;
    bool conceal;
    MUNUSED bool seperation;
    MUNUSED bool flash;
    bool doubleheight;
    MUNUSED bool blink;
    bool hold;
    bool endbox;
    bool startbox;
    bool withinbox;

    unsigned char last_ch = ' ';
    unsigned char ch;

    uint fgcolor    = kTTColorWhite;
    uint bgcolor    = kTTColorBlack;
    uint newfgcolor = kTTColorWhite;
    uint newbgcolor = kTTColorBlack;

    if (m_teletextReader->IsSubtitle() || m_teletextReader->IsTransparent())
    {
        bgcolor    = kTTColorTransparent;
        newbgcolor = kTTColorTransparent;

        bool isBlank = true;
        for (uint i = (row == 1 ? 8 : 0); i < (uint) kTeletextColumns; i++)
        {
            ch = page[i] & 0x7F;
            if (ch != ' ')
            {
                isBlank = false;
                break;
            }
        }

        if (isBlank)
            return;
    }

    SetForegroundColor(fgcolor);
    SetBackgroundColor(bgcolor);

    mosaic = false;
    seperation = false;
    conceal = false;
    flash = false;
    doubleheight = false;
    blink = false;
    hold = false;
    endbox = false;
    startbox = false;
    withinbox = false;
    uint flof_link_count = 0;
    uint old_bgcolor = bgcolor;

    if (row == 1)
    {
        for (uint x = 0; x < 8; x++)
            DrawBackground(x, 1);
    }

    for (uint x = (row == 1 ? 8 : 0); x < (uint)kTeletextColumns; ++x)
    {
        if (startbox)
        {
            old_bgcolor = bgcolor;
            if (kTTColorTransparent & bgcolor)
                bgcolor = bgcolor & ~kTTColorTransparent;
            startbox = false;
            withinbox = true;
        }

        if (endbox)
        {
            bgcolor = old_bgcolor;
            endbox = false;
            withinbox = false;
        }

        SetForegroundColor(fgcolor);
        SetBackgroundColor(bgcolor);

        ch = page[x] & 0x7F;
        switch (ch)
        {
            case 0x00: case 0x01: case 0x02: case 0x03:
            case 0x04: case 0x05: case 0x06: case 0x07: // alpha + foreground color
                fgcolor = ch & 7;
                mosaic = false;
                conceal = false;
                // increment FLOF/FastText count if menu item detected
                flof_link_count += (row == 25) ? 1 : 0;
                goto ctrl;
            case 0x08: // flash
                // XXX
                goto ctrl;
            case 0x09: // steady
                flash = false;
                goto ctrl;
            case 0x0a: // end box
                endbox = true;
                goto ctrl;
            case 0x0b: // start box
                if (x < kTeletextColumns - 1 && ((page[x + 1] & 0x7F) == 0x0b))
                    startbox = true;
                goto ctrl;
            case 0x0c: // normal height
                doubleheight = false;
                goto ctrl;
            case 0x0d: // double height
                doubleheight = (row < (kTeletextRows-1)) && (x < (kTeletextColumns - 1));
                goto ctrl;

            case 0x10: case 0x11: case 0x12: case 0x13:
            case 0x14: case 0x15: case 0x16: case 0x17: // graphics + foreground color
                fgcolor = ch & 7;
                mosaic = true;
                conceal = false;
                goto ctrl;
            case 0x18: // conceal display
                conceal = true;
                goto ctrl;
            case 0x19: // contiguous graphics
                seperation = false;
                goto ctrl;
            case 0x1a: // separate graphics
                seperation = true;
                goto ctrl;
            case 0x1c: // black background
                bgcolor = kTTColorBlack;
                goto ctrl;
            case 0x1d: // new background
                bgcolor = fgcolor;
                goto ctrl;
            case 0x1e: // hold graphics
                hold = true;
                goto ctrl;
            case 0x1f: // release graphics
                hold = false;
                goto ctrl;
            case 0x0e: // SO (reserved, double width)
            case 0x0f: // SI (reserved, double size)
            case 0x1b: // ESC (reserved)
                ch = ' ';
                break;
            ctrl:
                ch = ' ';
                if (hold && mosaic)
                    ch = last_ch;
            break;

            default:
                if ((ch >= 0x80) && (ch <=0x9f)) // these aren't used
                    ch = ' '; // BAD_CHAR;
                else
                {
                    if (conceal && !m_teletextReader->RevealHidden())
                        ch = ' ';
                }
                break;
        }

        // Hide FastText/FLOF menu characters if not available
        if (flof_link_count && (flof_link_count <= 6))
        {
            const TeletextSubPage *ttpage = m_teletextReader->FindSubPage();

            if (ttpage)
            {
                bool has_flof = ttpage->floflink[flof_link_count - 1];
                ch = (has_flof) ? ch : ' ';
            }
        }

        newfgcolor = fgcolor;
        newbgcolor = bgcolor;

        SetForegroundColor(newfgcolor);
        SetBackgroundColor(newbgcolor);
        if ((row != 0) || (x > 7))
        {
            if (m_teletextReader->IsTransparent())
                SetBackgroundColor(kTTColorTransparent);

            if (withinbox || !m_teletextReader->IsSubtitle())
            {
                DrawBackground(x, row);
                if (doubleheight && row < (uint)kTeletextRows)
                    DrawBackground(x, row + 1);

                if ((mosaic) && (ch < 0x40 || ch > 0x5F))
                {
                    SetBackgroundColor(newfgcolor);
                    DrawMosaic(x, row, ch, doubleheight);
                }
                else
                {
                    char c2 = cvt_char(ch, lang);
                    DrawCharacter(x, row, c2, doubleheight);
                }
            }
        }
    }
}
示例#14
0
文件: emu.cpp 项目: ryban/DCPPU16
int main(int argc, char *argv[])
{
    if(argc < 2)
    {
        cerr << "usage: dcpu <flags> <filename>\n";
        return 1;
    }

    bool debug = false;
    int time_to_kill_ms = 0;

    // -d runs in debug mode, prints out memory dump at end

    for(int a = 1; a < argc - 1; a++)
    {
        if(!strcmp(argv[a], "-d"))
        {
            debug = true;
        }else
        {
            cerr << "invalid command <" << argv[a] << ">. ignoring\n";
        }
    }

    ifstream inFile(argv[argc - 1], ios::in);
    if(!inFile.good())
    {
        cerr << "Could not open <" << argv[argc - 1] << ">\n";
        return 1;
    }

    Dcpu cpu(inFile, debug);

    sf::Thread cpu_thread(&start, &cpu);

    sf::RenderWindow app(sf::VideoMode(TERMINAL_WIDTH * 4 * 4, TERMINAL_HEIGHT * 8 * 4), "DCPPU: DCPU-16 Emulator");

    app.SetFramerateLimit(30); // Getting 1500 fps on somthing this simple seems wasteful

    sf::Image font;
    if(!font.LoadFromFile("font.png"))
    {
        cerr << "Could not load font\n";
        return 1;
    }

    unsigned short *buf = cpu.GetScreenBuffer();
    buf += TERMINAL_WIDTH * TERMINAL_HEIGHT;

    // load and encode character set into RAM
    for(int char_off = 0; char_off < 128; char_off++)
    {
        int font_off_x = (char_off * 4) % 128;
        int font_off_y = ((char_off * 4) / 128) * 8;

        unsigned int font_char = 0;
        int x_ = 0;
        int y_ = 0;
        for(int x = font_off_x; x < font_off_x + 4; x++)
        {
            for(int y = font_off_y; y < font_off_y + 8; y++)
            {
                sf::Color pix = font.GetPixel(x, y); 
                if(pix != sf::Color(2, 1, 2))
                    font_char |= 1 << (31-((y_ * 4) + x_));
                y_++;
            }
            x_++;
        }
        unsigned short lowerword = font_char & 0xffff;
        unsigned short upperword = (font_char >> 16) & 0xffff;
        buf[char_off * 2] = upperword;
        buf[char_off * 2 + 1] = lowerword;
    }


    sf::Image screen;
    screen.Create(128, 96); // create black image
    screen.SetSmooth(false);
    sf::Sprite screen_sprite(screen);
    screen_sprite.SetScale(4.0, 4.0);

    cpu_thread.Launch();

    bool running = true;
    while(running)
    {
        sf::Event Event;
        while(app.GetEvent(Event))
        {
            if(Event.Type == sf::Event::Closed)
            {
                cpu.kill();
                running = false;
                app.Close();
            }
            if (Event.Type == sf::Event::TextEntered)
            {
                if (Event.Text.Unicode < 128)
                {
                    char c = static_cast<char>(Event.Text.Unicode);
                    cpu.PushInBuff(c);
                }
            }

        }
        app.Clear();

        unsigned short *buffer = cpu.GetScreenBuffer();

        for(int y = 0; y < TERMINAL_HEIGHT; y++)
        {
            for(int x = 0; x < TERMINAL_WIDTH; x++)
            {
                unsigned short sc = buffer[y * 32 + x];
                int fg_off = (sc >> 12) & 0xf;
                int bg_off = (sc >> 8) & 0xf;
                sf::Color fg = color_table[fg_off];
                sf::Color bg = color_table[bg_off];
                char c = sc & 0x7f;
                bool blink = (sc & 0x80) == 0x80 && (time(0) % 2 == 0); // if bit 15 set, blink on for 1 sec, off for 1 sec

                DrawCharacter(screen, buffer + (TERMINAL_WIDTH*TERMINAL_HEIGHT), c, fg, bg, blink, x, y);
            }
        }

        app.Draw(screen_sprite);
        app.Display();
    }
    
    return 0;
}