~ubuntu-branches/ubuntu/lucid/xscreensaver/lucid

« back to all changes in this revision

Viewing changes to hacks/apple2.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2007-12-06 09:53:12 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20071206095312-fkzcwe4vqm50z208
Tags: 5.04-1ubuntu1
* Merge from debian unstable, remaining changes:
  - split xscreensaver into xscreensaver, xscreensaver-data (hacks we ship),
    xscreensaver-data-extra (hacks in universe). split out gl hacks for
    universe to xscreensaver-gl-extra
  - use fridge for rss screensavers
  - create and install .desktop files for gnome-screensaver

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* xscreensaver, Copyright (c) 1998-2004 Jamie Zawinski <jwz@jwz.org>
 
1
/* xscreensaver, Copyright (c) 1998-2006 Jamie Zawinski <jwz@jwz.org>
2
2
 *
3
3
 * Permission to use, copy, modify, distribute, and sell this software and its
4
4
 * documentation for any purpose is hereby granted without fee, provided that
13
13
 */
14
14
 
15
15
#include <math.h>
16
 
#include "screenhack.h"
 
16
#include "screenhackI.h"
17
17
#include "apple2.h"
18
 
#include <time.h>
19
 
#include <sys/time.h>
20
 
#include <X11/Intrinsic.h>
21
18
 
22
19
#ifdef HAVE_XSHM_EXTENSION
23
20
#include "xshm.h"
25
22
 
26
23
#define DEBUG
27
24
 
28
 
extern XtAppContext app;
29
 
 
30
25
/*
31
26
 * Implementation notes
32
27
 *
233
228
  if (y<0 || y>=192 || x<0 || x>=280) return;
234
229
 
235
230
  for (run=0; run<2 && x<280; run++) {
236
 
    u_char *vidbyte = &st->hireslines[y][x/7];
237
 
    u_char whichbit=1<<(x%7);
 
231
    unsigned char *vidbyte = &st->hireslines[y][x/7];
 
232
    unsigned char whichbit=1<<(x%7);
238
233
    int masked_bit;
239
234
 
240
235
    *vidbyte = (*vidbyte & 0x7f) | highbit;
308
303
a2_plot(apple2_state_t *st, int color, int x, int y)
309
304
{
310
305
  int textrow=y/2;
311
 
  u_char byte;
 
306
  unsigned char byte;
312
307
 
313
308
  if (x<0 || x>=40 || y<0 || y>=48) return;
314
309
 
358
353
    case 1:
359
354
      n=random()%500;
360
355
      for (i=0; i<n && addr<0x4000; i++) {
361
 
        u_char rb=((random()%6==0 ? 0 : random()%16) |
 
356
        unsigned char rb=((random()%6==0 ? 0 : random()%16) |
362
357
                   ((random()%5==0 ? 0 : random()%16)<<4));
363
358
        a2_poke(st, addr++, rb);
364
359
      }
396
391
}
397
392
 
398
393
 
 
394
#if 1  /* jwz: since MacOS doesn't have "6x10", I dumped this font to an XBM...
 
395
        */
 
396
 
 
397
#include "images/apple2font.xbm"
 
398
 
 
399
static void
 
400
a2_make_font(apple2_sim_t *sim)
 
401
{
 
402
  Pixmap text_pm = XCreatePixmapFromBitmapData (sim->dpy, sim->window,
 
403
                                                (char *) apple2_font_bits,
 
404
                                                apple2_font_width,
 
405
                                                apple2_font_height,
 
406
                                                1, 0, 1);
 
407
  if (apple2_font_width != 64*7) abort();
 
408
  if (apple2_font_height != 8) abort();
 
409
  sim->text_im = XGetImage(sim->dpy, text_pm, 0, 0, 
 
410
                           apple2_font_width, apple2_font_height,
 
411
                           ~0L, ZPixmap);
 
412
  XFreePixmap(sim->dpy, text_pm);
 
413
}
 
414
 
 
415
#else /* 0 */
 
416
 
399
417
/* This table lists fixes for characters that differ from the standard 6x10
400
418
   font. Each encodes a pixel, as (charindex*7 + x) + (y<<10) + (value<<15)
401
419
   where value is 0 for white and 1 for black. */
402
 
static unsigned short a2_fixfont[] = {
 
420
static const unsigned short a2_fixfont[] = {
403
421
  /* Fix $ */  0x8421, 0x941d,
404
422
  /* Fix % */  0x8024, 0x0028, 0x8425, 0x0426, 0x0825, 0x1027, 0x1426, 0x9427,
405
423
               0x1824, 0x9828,
470
488
    abort();
471
489
  }
472
490
 
473
 
  text_pm=XCreatePixmap(sim->dpy, sim->window, 64*7, 8, sim->dec->xgwa.depth);
 
491
  text_pm=XCreatePixmap(sim->dpy, sim->window, 64*7, 8, 1);
474
492
 
475
493
  memset(&gcv, 0, sizeof(gcv));
476
494
  gcv.foreground=1;
492
510
      XDrawString(sim->dpy, text_pm, gc, x, y, &c, 1);
493
511
    }
494
512
  }
 
513
 
 
514
# if 0
 
515
  for (i=0; a2_fixfont[i]; i++) {
 
516
    XSetForeground (sim->dpy, gc, (a2_fixfont[i]>>15)&1);
 
517
    XDrawPoint(sim->dpy, text_pm, gc, a2_fixfont[i]&0x3ff,
 
518
              (a2_fixfont[i]>>10)&0xf);
 
519
  }
 
520
  XWriteBitmapFile(sim->dpy, "/tmp/a2font.xbm", text_pm, 64*7, 8, -1, -1);
 
521
# endif
 
522
 
495
523
  sim->text_im = XGetImage(sim->dpy, text_pm, 0, 0, 64*7, 8, ~0L, ZPixmap);
496
524
  XFreeGC(sim->dpy, gc);
497
525
  XFreePixmap(sim->dpy, text_pm);
503
531
  }
504
532
}
505
533
 
 
534
#endif /* 0 */
506
535
 
507
 
void
508
 
apple2(Display *dpy, Window window, int delay,
509
 
       void (*controller)(apple2_sim_t *sim,
510
 
                          int *stepno,
511
 
                          double *next_actiontime))
 
536
apple2_sim_t *
 
537
apple2_start(Display *dpy, Window window, int delay,
 
538
             void (*controller)(apple2_sim_t *sim,
 
539
                                int *stepno,
 
540
                                double *next_actiontime))
512
541
{
513
 
  int i,textrow,row,col,stepno;
514
 
  int c;
515
 
  double next_actiontime;
516
542
  apple2_sim_t *sim;
517
543
 
518
 
  sim=(apple2_sim_t *)calloc(1,sizeof(apple2_state_t));
 
544
  sim=(apple2_sim_t *)calloc(1,sizeof(apple2_sim_t));
519
545
  sim->dpy = dpy;
520
546
  sim->window = window;
521
547
  sim->delay = delay;
 
548
  sim->controller = controller;
522
549
 
523
550
  sim->st = (apple2_state_t *)calloc(1,sizeof(apple2_state_t));
524
551
  sim->dec = analogtv_allocate(dpy, window);
525
 
  sim->dec->event_handler = screenhack_handle_event;
526
552
  sim->inp = analogtv_input_allocate();
527
553
 
528
554
  sim->reception.input = sim->inp;
545
571
 
546
572
  a2_make_font(sim);
547
573
 
548
 
  stepno=0;
 
574
  sim->stepno=0;
549
575
  a2_goto(sim->st,23,0);
550
576
 
551
577
  if (random()%2==0) sim->basetime_tv.tv_sec -= 1; /* random blink phase */
552
 
  next_actiontime=0.0;
 
578
  sim->next_actiontime=0.0;
553
579
 
554
580
  sim->curtime=0.0;
555
 
  next_actiontime=sim->curtime;
556
 
  (*controller)(sim, &stepno, &next_actiontime);
 
581
  sim->next_actiontime=sim->curtime;
 
582
  sim->controller (sim, &sim->stepno, &sim->next_actiontime);
557
583
 
558
584
# ifdef GETTIMEOFDAY_TWO_ARGS
559
585
  gettimeofday(&sim->basetime_tv, NULL);
561
587
  gettimeofday(&sim->basetime_tv);
562
588
# endif
563
589
 
564
 
  while (1) {
 
590
  return sim;
 
591
}
 
592
 
 
593
int
 
594
apple2_one_frame (apple2_sim_t *sim)
 
595
{
565
596
    double blinkphase;
 
597
    int i;
 
598
    int textrow;
 
599
 
 
600
    if (sim->stepno==A2CONTROLLER_DONE)
 
601
      goto DONE;  /* when caller says we're done, be done, dammit! */
566
602
 
567
603
    {
568
604
      struct timeval curtime_tv;
578
614
        sim->dec->powerup=sim->curtime;
579
615
    }
580
616
 
581
 
    if (analogtv_handle_events(sim->dec)) {
582
 
      sim->typing=NULL;
583
 
      sim->printing=NULL;
584
 
      stepno=A2CONTROLLER_FREE;
585
 
      next_actiontime = sim->curtime;
586
 
      (*controller)(sim, &stepno, &next_actiontime);
587
 
      stepno=0;
588
 
      sim->controller_data=NULL;
589
 
      sim->st->gr_mode=0;
590
 
      continue;
591
 
    }
592
 
 
593
617
    blinkphase=sim->curtime/0.8;
594
618
 
595
619
    /* The blinking rate was controlled by 555 timer with a resistor/capacitor
603
627
      /* For every row with blinking text, set the changed flag. This basically
604
628
         works great except with random screen garbage in text mode, when we
605
629
         end up redrawing the whole screen every second */
 
630
      int row, col;
606
631
      for (row=(sim->st->gr_mode ? 20 : 0); row<24; row++) {
607
632
        for (col=0; col<40; col++) {
608
 
          c=sim->st->textlines[row][col];
 
633
          int c=sim->st->textlines[row][col];
609
634
          if ((c & 0xc0) == 0x40) {
610
635
            downcounter=4;
611
636
            break;
617
642
      }
618
643
    }
619
644
 
620
 
    if (sim->curtime >= delay)
621
 
      stepno = A2CONTROLLER_DONE;
 
645
    if (sim->curtime >= sim->delay)
 
646
      sim->stepno = A2CONTROLLER_DONE;
622
647
 
623
648
    if (sim->printing) {
624
649
      int nlcnt=0;
640
665
      }
641
666
      if (!*sim->printing) sim->printing=NULL;
642
667
    }
643
 
    else if (sim->curtime >= next_actiontime) {
 
668
    else if (sim->curtime >= sim->next_actiontime) {
644
669
      if (sim->typing) {
645
670
 
646
671
        int c;
653
678
        else {
654
679
          a2_printc(sim->st, c);
655
680
          if (c=='\r' || c=='\n') {
656
 
            next_actiontime = sim->curtime;
 
681
            sim->next_actiontime = sim->curtime;
657
682
          }
658
683
          else if (c==010) {
659
 
            next_actiontime = sim->curtime + 0.1;
 
684
            sim->next_actiontime = sim->curtime + 0.1;
660
685
          }
661
686
          else {
662
 
            next_actiontime = (sim->curtime +
 
687
            sim->next_actiontime = (sim->curtime +
663
688
                               (((random()%1000)*0.001 + 0.3) *
664
689
                                sim->typing_rate));
665
690
          }
666
691
        }
667
692
      } else {
668
 
        next_actiontime=sim->curtime;
669
 
 
670
 
        (*controller)(sim, &stepno, &next_actiontime);
671
 
        if (stepno==A2CONTROLLER_DONE) goto finished;
 
693
        sim->next_actiontime = sim->curtime;
 
694
 
 
695
        sim->controller (sim, &sim->stepno, &sim->next_actiontime);
 
696
 
 
697
        if (sim->stepno==A2CONTROLLER_DONE) {
 
698
 
 
699
        DONE:
 
700
          sim->stepno=A2CONTROLLER_FREE;
 
701
          sim->controller (sim, &sim->stepno, &sim->next_actiontime);
 
702
 
 
703
          XClearWindow(sim->dpy, sim->window);
 
704
 
 
705
          /* #### free sim? */
 
706
          return 0;
 
707
        }
672
708
 
673
709
      }
674
710
    }
678
714
    analogtv_setup_frame(sim->dec);
679
715
 
680
716
    for (textrow=0; textrow<24; textrow++) {
 
717
      int row;
681
718
      for (row=textrow*8; row<textrow*8+8; row++) {
682
719
 
683
720
        /* First we generate the pattern that the video circuitry shifts out
691
728
 
692
729
        if ((sim->st->gr_mode&A2_GR_HIRES) &&
693
730
            (row<160 || (sim->st->gr_mode&A2_GR_FULL))) {
 
731
          int col;
694
732
 
695
733
          /* Emulate the mysterious pink line, due to a bit getting
696
734
             stuck in a shift register between the end of the last
701
739
          }
702
740
 
703
741
          for (col=0; col<40; col++) {
704
 
            u_char b=sim->st->hireslines[row][col];
 
742
            unsigned char b=sim->st->hireslines[row][col];
705
743
            int shift=(b&0x80)?0:1;
706
744
 
707
745
            /* Each of the low 7 bits in hires mode corresponded to 2 dot
716
754
        }
717
755
        else if ((sim->st->gr_mode&A2_GR_LORES) &&
718
756
                 (row<160 || (sim->st->gr_mode&A2_GR_FULL))) {
 
757
          int col;
719
758
          for (col=0; col<40; col++) {
720
 
            u_char nib=((sim->st->textlines[textrow][col] >> (((row/4)&1)*4))
 
759
            unsigned char nib=((sim->st->textlines[textrow][col] >> (((row/4)&1)*4))
721
760
                        & 0xf);
722
761
            /* The low or high nybble was shifted out one bit at a time. */
723
762
            for (i=0; i<14; i++) {
729
768
          }
730
769
        }
731
770
        else {
 
771
          int col;
732
772
          for (col=0; col<40; col++) {
733
773
            int rev;
734
 
            c=sim->st->textlines[textrow][col]&0xff;
 
774
            int c=sim->st->textlines[textrow][col]&0xff;
735
775
            /* hi bits control inverse/blink as follows:
736
776
               0x00: inverse
737
777
               0x40: blink
756
796
    analogtv_reception_update(&sim->reception);
757
797
    analogtv_add_signal(sim->dec, &sim->reception);
758
798
    analogtv_draw(sim->dec);
759
 
  }
760
 
 
761
 
 finished:
762
 
 
763
 
  stepno=A2CONTROLLER_FREE;
764
 
  (*controller)(sim, &stepno, &next_actiontime);
765
 
 
766
 
  XSync(sim->dpy, False);
767
 
  XClearWindow(sim->dpy, sim->window);
 
799
 
 
800
    return 1;
768
801
}
769
802
 
 
803
 
 
804
#if 0
770
805
void
771
806
a2controller_test(apple2_sim_t *sim, int *stepno, double *next_actiontime)
772
807
{
810
845
    break;
811
846
  }
812
847
}
 
848
#endif