User Tag List

Показано с 1 по 2 из 2

Тема: Сишный исходник просмотрщика спектрумовской графики для Спринтера

  1. #1
    Master Аватар для Shaos
    Регистрация
    16.01.2005
    Адрес
    California, USA
    Сообщений
    807
    Спасибо Благодарностей отдано 
    100
    Спасибо Благодарностей получено 
    99
    Поблагодарили
    66 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Сишный исходник просмотрщика спектрумовской графики для Спринтера

    Передаю в общественное достояние графическую программу просмотра спектрумовской графики в форматах SCR (6912 и 6144 байта), ATR (768 байт) и IMG (Gigascreen 13824 байта), написанную мной в марте-апреле прямо на Спринтере Sp2000 для компиляции в SOLiD-C - вот батник для сборки:
    Код:
    set PROG=zxview
    set PREFIX=C:\SOLID\EXAMPLES
    REM SolidC EXE files must be in PATH
    cls 2
    del %PROG%.exe
    cc1 -m %PREFIX%\%PROG%
    cc2 %PREFIX%\%PROG%
    as %PREFIX%\%PROG%
    REM LD filename length is limited to 12 characters!
    %PREFIX%\ld /R6DF0 /P6E00 %PROG%,clib/l/gXMAIN /x
    REM %PREFIX%\ld %PROG%,clib/l/gXMAIN /x
    REM del %PROG%.tmc
    REM del %PROG%.rel
    REM del %PROG%.asm
    Исходник программы:
    Код:
    /* ZXVIEW.C - Alexander "Shaos" Shabarshin <[email protected]>
    							 
       25-MAR-2021 - initial version for Solid-C that shows SCR and IMG
       26-MAR-2021 - v1.0 optimized and linked from 0x7000 to avoid screen snowing
       27-MAR-2021 - v1.1 implemented gamma correction as per sRGB (gamma=2.2)
       23-APR-2021 - v1.2 implemented incomplete palette filling and B/W SCR
       25-APR-2021 - v1.3 fixed incomplete palette and also ATR support
       09-MAY-2021 - v1.4 rolled back pallette function update
    
       This code is PUBLIC DOMAIN - use it on your own RISK! */
    
    #include <malloc.h>
    #include <stdio.h>
    #include <conio.h>
    #include <dos.h>
    #include <mem.h>
    
    #define SCRSIZE 6912
    #define ATRSIZE 768
    #define BWSCRSZ 6144
    
    union REGS inregs,outregs;
    int oldmode,oldpage;
    char *scr;
    FILE *f;
    
    #define WINDOW3   0xE2 /* Port for memory page 0xC000...0xFFFF */
    #define PORT_Y    0x89 /* Port to set Y for videomemory */
    
    /*
    
    Color number	Binary value	BRIGHT 0 (RGB)	 BRIGHT 1 (RGB)	 Color name
    ---------------------------------------------------------------------------
          0		    000		#000000		 #000000	 black
          1		    001		#0000CD		 #0000FF	 blue
          2		    010		#CD0000		 #FF0000	 red
          3		    011		#CD00CD		 #FF00FF	 magenta
          4		    100		#00CD00		 #00FF00	 green
          5		    101		#00CDCD		 #00FFFF	 cyan
          6		    110		#CDCD00		 #FFFF00	 yellow
          7		    111		#CDCDCD		 #FFFFFF	 white
    */
    
    setpal()
    {
    /* sRGB scale (gamma=2.2): 0%    ----  20%   40%   60%   80%   100% */
       static char scale[] = { 0x00, 0x0E, 0x7C, 0xAA, 0xCB, 0xE7, 0xFF };
       static char *po = (char*)(0xC000+992); /* address to apply palette */
       static int i,c1,c2;
       for(i=0;i<256;i++)
       {
          outp(PORT_Y,(char)i);
          /* palette_index = (first_color<<4)|second_color */
          c1 = (i&0x80)?3:2;
          c2 = (i&0x08)?3:2;
          po[2] = scale[((i&0x10)?c1:0)+((i&0x01)?c2:0)];
          po[0] = scale[((i&0x20)?c1:0)+((i&0x02)?c2:0)];
          po[1] = scale[((i&0x40)?c1:0)+((i&0x04)?c2:0)];
       }
    }
        
    int getsize()
    {
       static f_point *fp;
       fseek(f,0,0,SEEK_END);
       fp = ftell(f);
       fseek(f,0,0,SEEK_SET);
       return fp->low;
    }
    
    int fread1(buf,sz,f)
    char* buf;
    int sz;
    FILE *f;
    {
     static int i,o,r;
     r = 0;
     for(i=0;i<sz;i++)
     {
        o = fgetc(f);
        if(o < 0) break;
        buf[i] = o;
        r++;
     }
     return r;
    }
    
    main(argc,argv)
    int argc;
    char** argv;
    {              
        int sz;
        static char c1,c2,*po;
        static int i,j,k,l,l1,l2;
        static int atr1,atr2,pla1,pla2;
                                                   
        printf("ZXVIEW v1.4 - viewer for SCR, ATR and IMG (Gigascreen) graphics\n");
        printf("This code is PUBLIC DOMAIN - use it on your own RISK!\n");
        printf("Created by Shaos in March-April 2021 for SOLiD-C examples\n");
        printf("http://sprinter.nedopc.org\n");
        if(argc<2) 
        {
           printf("\nUsage: zxview path-to-file\n\n");
           exit(-1);
        }
    
        scr = (char*)malloc(SCRSIZE*2);
        if(scr==NULL) exit(-2);
        printf("Screen buffer 0x%X...0x%X\n",scr,scr+SCRSIZE*2-1);
        l = (int)(&inregs);
        printf("Data start: 0x%X\n",l);
    
        f = fopen(argv[1],"rb");
        if(f==NULL) exit(-3);
        sz = getsize();
        j = -1;
        i = fread1(scr,sz,f);
        if(sz==ATRSIZE)
        {    
           memcpy(&scr[BWSCRSZ],scr,ATRSIZE);
           memcpy(&scr[BWSCRSZ+SCRSIZE],scr,ATRSIZE);
           for(l=0;l<12;l++)
           {              
              l1 = l<<9;
              l2 = l1 + 256;
              memset(&scr[l1],0x55,256);
              memset(&scr[l2],0xAA,256);
              memset(&scr[l1+SCRSIZE],0x55,256);
              memset(&scr[l2+SCRSIZE],0xAA,256);
           }
        }
        else if(sz<=SCRSIZE)
        {
           fseek(f,0,0,SEEK_SET);
           j = fread1(&scr[SCRSIZE],sz,f);
        }
        fclose(f);
        printf("File %s (%d) - read %d %d\n",argv[1],sz,i,j);
    
        if(i==BWSCRSZ) /* B/W SCR */
        {
           for(j=BWSCRSZ;j<SCRSIZE;j++)
           {
              scr[j] = 0x07;
              scr[j+SCRSIZE] = 0x07;
           }
        }
                                                                
        inregs.h.c = 0x51;
        intdos(&inregs,&outregs);
        oldmode = (outregs.x.bc & 0xFF00) | outregs.h.a;
        printf("Old mode %04X\n",oldmode);
    
        inregs.h.c = 0x50;
        inregs.h.b = 0;
        inregs.h.a = 0x81;
        intdos(&inregs,&outregs);
     
        oldpage = inp(WINDOW3);
        outp(WINDOW3,0x50);
    
        setpal();                
    
        for(j=0;j<192;j++)
        {
    //      if(kbhit()) break;
          po = (char*)0xC020; /* it's not a constant - it's incremented below! */
          outp(PORT_Y,(char)(j+32));
          l1 = SCRSIZE-768+((j&0xF8)<<2);
          l2 = ((j&0xC0)<<5)+((j&0x07)<<8)+((j&0x38)<<2);
          for(i=0;i<32;i++)
          {                         
             l = l1 + i;
             atr1 = scr[l];
             atr2 = scr[l+SCRSIZE];
             l = l2 + i;
             pla1 = scr[l];
             pla2 = scr[l+SCRSIZE];
             l = 0x80;
             for(k=0;k<8;k++)
             {     
                if(pla1 & l)
                   c1 = atr1&7;
                else
                   c1 = (atr1>>3)&7; 
                if(pla2 & l)
                   c2 = atr2&7;
                else
                   c2 = (atr2>>3)&7;
                if(atr1 & 0x40) c1 += 8;
                if(atr2 & 0x40) c2 += 8;
                if(c1 >= c2)
                   *po++ = (c1<<4)|c2;
                else
                   *po++ = (c2<<4)|c1;
                l >>= 1;
             }
          }
        }
    
        getch();
    
        free(scr);
    
        outp(WINDOW3,oldpage);
    
        inregs.x.bc = oldmode;
        inregs.h.a = oldmode & 255;
        inregs.h.c = 0x50;
        intdos(&inregs,&outregs);
    
    }
    - - - Добавлено - - -

    Кое какие пояснения по коду - в данный момент fread на солиде глючит, поэтому я написал свою заглушку int fread1(buf,sz,f) работающую через fgetc

    Сохранение текущего графического режима с видеостраницей:
    Код:
        inregs.h.c = 0x51;
        intdos(&inregs,&outregs);
        oldmode = (outregs.x.bc & 0xFF00) | outregs.h.a;
        printf("Old mode %04X\n",oldmode);
    Установка графического режима 320x256 256 цветов:
    Код:
        inregs.h.c = 0x50;
        inregs.h.b = 0;
        inregs.h.a = 0x81;
        intdos(&inregs,&outregs);
    Сохранение страницы памяти в последнем окне и установка туда графической страницы #50:
    Код:
        oldpage = inp(WINDOW3);
        outp(WINDOW3,0x50);
    Хитрая 256-цветная палитра создаётся процедурно и записывается в видеопамять по смещению 992 (палитра №0) в функции setpal():

    Код:
    setpal()
    {
    /* sRGB scale (gamma=2.2): 0%    ----  20%   40%   60%   80%   100% */
       static char scale[] = { 0x00, 0x0E, 0x7C, 0xAA, 0xCB, 0xE7, 0xFF };
       static char *po = (char*)(0xC000+992); /* address to apply palette */
       static int i,c1,c2;
       for(i=0;i<256;i++)
       {
          outp(PORT_Y,(char)i);
          /* palette_index = (first_color<<4)|second_color */
          c1 = (i&0x80)?3:2;
          c2 = (i&0x08)?3:2;
          po[2] = scale[((i&0x10)?c1:0)+((i&0x01)?c2:0)];
          po[0] = scale[((i&0x20)?c1:0)+((i&0x02)?c2:0)];
          po[1] = scale[((i&0x40)?c1:0)+((i&0x04)?c2:0)];
       }
    }
    Хитрость заключается в том, что взяв 2 спектрумовских 4-битных цвета c1 и c2 можно легко получить их смешение (причём с учётом гаммы sRGB) как цвет в этой 256-цветной палитре по индексу (c1<<4)|c2

    Далее засылаем координату Y в порт #89 outp(PORT_Y,y) и пишем нужный цвет по смещению 0xC000+x (используя координату X для отступа от начала последнего окна памяти) - всё просто

    - - - Добавлено - - -

    Ну и в конце код возврата старой страницы памяти в последнее окно и возвращение старого графического режима со старой видеостраницей:
    Код:
        outp(WINDOW3,oldpage);
    
        inregs.x.bc = oldmode;
        inregs.h.a = oldmode & 255;
        inregs.h.c = 0x50;
        intdos(&inregs,&outregs);
    - - - Добавлено - - -

    Для сравнения вот как просмотрщик показывает гигаскриновскую картинку в эмуляторе (нижняя картинка) рядом с картинкой из ZXArt.ee (верхняя картинка):



    IMG-файлы взяты по следующим ссылкам:
    https://zxart.ee/rus/avtory/t/tutty/...-arthur-fleck/
    https://zxart.ee/rus/avtory/t/tmk/save-the-animals/
    https://zxart.ee/rus/avtory/r/riskej...anding-single/

    - - - Добавлено - - -

    P.S. Если кто-то придерживается мнения, что гигаскрин обязан мерцать, а у смотрящего из глаз должна сочиться кровь, лучше сюда ничего не писать

    P.P.S. Отдаю исходник в PUBLIC DOMAIN соответственно публика может делать с ним что захочет, а я в бижайшем будущем хочу добавить просмотр мультиколорных картинок и SXG (поэтому желательно релизить под другим названием и версионностью, если кто-то что-то поменяет в нём)
    Миниатюры Миниатюры Нажмите на изображение для увеличения. 

Название:	Screenshot from 2021-03-27 00-34-08.jpg 
Просмотров:	245 
Размер:	22.3 Кб 
ID:	75448   Нажмите на изображение для увеличения. 

Название:	Screenshot from 2021-03-27 00-32-08.jpg 
Просмотров:	237 
Размер:	21.8 Кб 
ID:	75447   Нажмите на изображение для увеличения. 

Название:	Screenshot from 2021-03-27 00-27-47.jpg 
Просмотров:	247 
Размер:	23.4 Кб 
ID:	75446  
    Вложения Вложения
    Последний раз редактировалось Shaos; 24.05.2021 в 01:43.
    Администратор сетевого сообщества nedoPC.org
    Урал 8/64К, Sp2000, ZX48K+, ZX16K (спалил), TS1000 (американский ZX81), TS2068, Дельта-С, 20 лет собираю ATM Turbo 2+
    Неспектрумы: Электроника МК-85 и МК-85М, ПК-01 Львов, БК-0011, Вектор-06Ц, Лик (спец), Апогеи, Radio-86RK SRAM 32K & 128K (всё ещё собираю)

  2. Эти 4 пользователя(ей) поблагодарили Shaos за это полезное сообщение:

    lostar-igor (23.05.2021), RomanRom2 (22.05.2021), sashapont (29.05.2021), Дмитрий (22.05.2021)

  3. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  4. #2
    Master Аватар для Shaos
    Регистрация
    16.01.2005
    Адрес
    California, USA
    Сообщений
    807
    Спасибо Благодарностей отдано 
    100
    Спасибо Благодарностей получено 
    99
    Поблагодарили
    66 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Вот универсальный батник SC.BAT для сборки простых сишных программ, состоящих из одного C-файла - он собирает EXE со стартовой точкой 4300h (это ок для текстовых программ, но для графических надо область переменных сдвигать за 8000h чтобы на экране небыло мусора - выше показано как это можно делать):
    Код:
    set PROG=%1
    set PREFIX=C:\SOLID\EXAMPLES
    REM SolidC EXE files must be in PATH on disk C!
    cls 2
    del %PROG%.exe
    cc1 -m %PREFIX%\%PROG%
    cc2 %PREFIX%\%PROG%
    as %PREFIX%\%PROG%
    REM LD filename length is limited to 12 characters!
    %PREFIX%\ld %PROG%,clib/l/gXMAIN /x
    del %PROG%.tmc
    del %PROG%.rel
    del %PROG%.asm
    Это батник SC.BAT, а также файлы LD.EXE и CLIB.IRL должны лежать в каталоге с исходником (т.к. LD пока не умеет работать с путями), а все остальные EXE-шники должны быть доступны через PATH, который задаётся в SYSTEM.BAT - ниже пример моего стартового BAT-файла:
    Код:
    @echo off
    set PATH=%BOOTDSK%\;%BOOTDSK%\FN\;%BOOTDSK%\BIN\;%BOOTDSK%\ZX\;%BOOTDSK%\SOLID\
    ver
    @echo on
    fn
    Пример простого исходника HELLO.C (он уже упоминался в соседнем топике):
    Код:
    #include <stdio.h>
    
    main()
    {
        printf("\nHello world !\n");
        fprintf(stdout,"Привет мир !\n");
    }
    Который собирается путём запуска команды SC.BAT HELLO

    P.S. Для совсем простого случая в батнике можно захардкодить имя файла set PROG=HELLO, чтобы можно было просто по Enter в FN его пускать (или мышью)
    Последний раз редактировалось Shaos; 31.07.2021 в 10:13.
    Администратор сетевого сообщества nedoPC.org
    Урал 8/64К, Sp2000, ZX48K+, ZX16K (спалил), TS1000 (американский ZX81), TS2068, Дельта-С, 20 лет собираю ATM Turbo 2+
    Неспектрумы: Электроника МК-85 и МК-85М, ПК-01 Львов, БК-0011, Вектор-06Ц, Лик (спец), Апогеи, Radio-86RK SRAM 32K & 128K (всё ещё собираю)

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Ответов: 55
    Последнее: 20.06.2020, 10:41
  2. Ответов: 51
    Последнее: 21.07.2014, 01:55
  3. Лучшие редакторы графики для C64
    от Surfin_Bird в разделе Commodore 16/64/128
    Ответов: 42
    Последнее: 01.10.2010, 14:40
  4. RGB значения для спектрумовской палитры.
    от moroz1999 в разделе Утилиты
    Ответов: 12
    Последнее: 26.04.2009, 21:18
  5. Нужен драйвер (или исходник) для NemoIDE
    от ALEXEY.GORDEEV в разделе Программирование
    Ответов: 4
    Последнее: 09.11.2008, 21:23

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •