Mam znowu podobny problem w implementacji algorytmu putpixel(), ale tym razem dotyczący trybu graficznego LOW (najważniejszego w Atari ST).
To ostatnia rzecz z którą mam największy kłopot, więc nie będę Was już męczył więcej w przyszłości.. ;)
A więc...
Nie radę sobie od dłuższego czasu z implementacją algorytmu rysującego pojedynczy piksel w trybie 320x200x16 kolorów.
Sprawa jest tym skomplikowana, że Atari ST używa bitplanów...
Rozdzielczość ta ma 16 kolorów, każdy kolor jest opisany 4 bitami (kod koloru od 0 do 15).
Ok, ustawmy sobie paletę kolorów dla np. trzech kolorów...
setcolor(0x700, 11); /* red */
setcolor(0x070, 12); /* green */
setcolor(0x007, 13); /* blue */
Jeśli chcę wyświetlić teraz piksel o kolorze niebieskim, to muszę zmodyfikować pierwszy bit w następnych czterech słowach...
Kod wyświetlający piksel (przykładowy kod w asemblerze Motorola 68000):
; rejestr a0 wskazuje na początek pamięci ekranu
move.w #%1000000000000000, (a0)
move.w #%0000000000000000, 2(a0)
move.w #%1000000000000000, 4(a0)
move.w #%1000000000000000, 6(a0)
1011 = 13 (kolor niebieski)
W asemblerze wiem jak to zrobić, bo kod rysuje piksel na sztywno, ale nie radzę sobie z napisaniem funkcji putpixel().
Kod w C jaki napisałem (ale nie działa poprawnie):
void low_put_pixel(u16 x, u16 y, u16 color, u16 *screen)
{
int c, k;
u8 color_bin[4];
/* tu zamieniam liczbę dziesiętną na binarną */
for (c = 0; c <= 3; c++) {
k = color >> c;
color_bin[c] = (k & 1) ? 1 : 0;
}
u16 offset = ((y * 320) + x) / 16;
u8 bitIndex = ((y * 320) + x) % 16;
if(color_bin[0]) {
screen[offset++] |= (1 << (15-bitIndex));
} else {
screen[offset++] &= ~(1 << (15-bitIndex));
}
if(color_bin[1]) {
screen[offset++] |= (1 << (15-bitIndex));
} else {
screen[offset++] &= ~(1 << (15-bitIndex));
}
if(color_bin[2]) {
screen[offset++] |= (1 << (15-bitIndex));
} else {
screen[offset++] &= ~(1 << (15-bitIndex));
}
if(color_bin[3]) {
screen[offset] |= (1 << (15-bitIndex));
} else {
screen[offset] &= ~(1 << (15-bitIndex));
}
}