-
Notifications
You must be signed in to change notification settings - Fork 0
/
powspot.c
160 lines (150 loc) · 3.64 KB
/
powspot.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <atari.h>
#include <stdio.h>
#include <dirent.h>
#include <conio.h>
#include <peekpoke.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
typedef unsigned word;
typedef unsigned char byte;
// Uncomment the following line to remove the help message and directory listing:
//#define SMALL_VERSION 1
// 8640 == 320*192*(9/8)/8. You can reduce this value up to the size of the biggest IMZ file
#define MAX_BUF 8640
static byte buffer[MAX_BUF];
static word compressed_length;
static byte * screenmem;
bool load_page(word num) {
static char filename[17];
static FILE * f;
POKE(710, 0x10); // background
sprintf(filename, "D:PAGE%d.IMZ", num);
f = fopen(filename, "r");
if (!f) {
POKE(710, 0); // background
return false;
}
compressed_length = fread(buffer, 1, MAX_BUF, f);
fclose(f);
POKE(710, 0); // background
return true;
}
void display_compressed_page() {
static word i;
static byte flags_count, flags;
static byte * screenmemwp; // tmp
POKE(710, 0xC0); // background
flags_count = 0;
screenmemwp = screenmem;
memset(screenmem, 0, 7680);
for (i = 0; i < compressed_length; i++) {
if (!flags_count) {
flags = buffer[i];
flags_count = 8;
} else if ((flags & 1) == 0) {
*screenmemwp++ = buffer[i];
flags >>= 1;
flags_count--;
} else {
static word len, j;
static byte off;
len = buffer[i]; off = buffer[++i];
for (j = len + 3; j; j--) {
*screenmemwp = *(byte*)((int)screenmemwp - off - 1);
screenmemwp++;
}
flags >>= 1;
flags_count--;
}
}
POKE(710, 0);
}
#if 0
// Example: filedump("D:PAGE0.IMZ", 0, 128);
void bindump(char * filename, int off, int len) {
int i;
FILE * fd = fopen(filename, "r");
if (!fd) {
printf("Error %d\n", errno);
return;
}
if (off) fseek(fd, off, SEEK_SET);
len = fread(buffer, 1, len, fd);
fclose(fd);
for (i = 0; i < len; i++) {
if ((i & 0xf) == 0) printf("%04X: ", i);
revers(i & 1);
cprintf("%02X", buffer[i]);
if ((i & 0xf) == 0xf) { revers(0); printf("\n"); }
}
}
#endif
void main(void) {
static word page;
static char c;
static bool forward, preloaded;
for (;;) {
page = 0;
forward = true;
#ifndef SMALL_VERSION
{
DIR * d;
struct dirent * de;
byte n = 0;
printf(" PowSpot! (by FCR)\n\nAvailable files:\n");
d = opendir("D:*.*");
while (de = readdir(d)) {
printf(" %-12s", de->d_name);
if (n++ == 2) {printf("\n"); n=0;}
}
if (n) printf("\n");
closedir(d);
}
printf("\nGo to next slide using SPACE or RETURN,\n"
"backwards with DELETE, and back to this\n"
"menu with ESC.\n\n");
#endif
POKE(710, 0x94); // restore background
printf("Enter page num. or RETURN to continue!\n> ");
cursor(1);
fgets(buffer, MAX_BUF, stdin);
page = atoi(buffer);
_graphics(24);
cursor(0);
screenmem = *(byte**)88;
POKE(709, 0x0F); // foreground
POKE(710, 0x10); // background
if (!load_page(page)) {
page = 0;
if (!load_page(0)) continue;
}
display_compressed_page();
preloaded = load_page(page + 1);
for (;;) {
while(!kbhit());
c = cgetc();
if (((c&0x7f) == ' ' || c == '\n') && (preloaded || !forward)) {
page++;
if (!forward) {
load_page(page);
forward = true;
}
display_compressed_page();
preloaded = load_page(page + 1);
} else if (c == CH_DEL && page) {
page--;
if (forward) {
load_page(page);
forward = false;
}
display_compressed_page();
preloaded = page > 0 && load_page(page - 1);
} else if (c == CH_ESC) {
break;
}
while (kbhit()) cgetc();
}
}
}