2024-05-29 19:55:33 +03:00
|
|
|
/*
|
2024-05-29 20:11:25 +03:00
|
|
|
* ______ ____ ______ _____ ______
|
2024-05-29 19:55:33 +03:00
|
|
|
* | ____| | _ \| ____| / / _ \| ____|
|
2024-05-29 20:11:25 +03:00
|
|
|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
|
2024-05-29 19:55:33 +03:00
|
|
|
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
|
|
|
|
* | | | | | __/ __/ |_) | |____ / / | | | | |
|
|
|
|
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Installation utility.
|
|
|
|
*
|
|
|
|
* See freebe.txt for copyright information.
|
|
|
|
*/
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
#include <allegro.h>
|
|
|
|
#include <bios.h>
|
2024-05-29 19:55:33 +03:00
|
|
|
#include <conio.h>
|
2024-05-29 20:11:25 +03:00
|
|
|
#include <ctype.h>
|
2024-05-29 19:55:33 +03:00
|
|
|
#include <go32.h>
|
2024-05-29 20:11:25 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <strings.h>
|
2024-05-29 19:55:33 +03:00
|
|
|
#include <sys/exceptn.h>
|
2024-05-29 20:11:25 +03:00
|
|
|
#include <sys/farptr.h>
|
|
|
|
#include <time.h>
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
#include "vbeaf.h"
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
#define VBEAF_FILENAME "c:\\vbeaf.drv"
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
#define ever \
|
|
|
|
; \
|
|
|
|
;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
/* info about one of the VBE/AF drivers */
|
2024-05-29 20:11:25 +03:00
|
|
|
typedef struct DRIVER_INFO {
|
|
|
|
char name[80];
|
|
|
|
AF_DRIVER *driver;
|
|
|
|
int driver_size;
|
|
|
|
char *notes;
|
|
|
|
int notes_size;
|
|
|
|
int present;
|
|
|
|
int accel;
|
|
|
|
int config;
|
2024-05-29 19:55:33 +03:00
|
|
|
} DRIVER_INFO;
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
#define MAX_DRIVERS 256
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
DRIVER_INFO driver_info[MAX_DRIVERS];
|
|
|
|
|
|
|
|
int num_drivers = 0;
|
|
|
|
|
|
|
|
char current_driver_name[80];
|
|
|
|
char current_driver_copyright[80];
|
|
|
|
|
|
|
|
/* graphics characters */
|
2024-05-29 20:11:25 +03:00
|
|
|
#define TL_CHAR 0xDA
|
|
|
|
#define TOP_CHAR 0xC4
|
|
|
|
#define TR_CHAR 0xBF
|
|
|
|
#define SIDE_CHAR 0xB3
|
|
|
|
#define BL_CHAR 0xC0
|
|
|
|
#define BR_CHAR 0xD9
|
|
|
|
#define SHADOW_CHAR 0xDB
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
/* drawing state variables */
|
|
|
|
int _text_color = 0;
|
|
|
|
int _text_x = 0;
|
|
|
|
int _text_y = 0;
|
|
|
|
|
|
|
|
int screen_h;
|
|
|
|
|
|
|
|
/* mouse driver state variables */
|
|
|
|
int m_state;
|
|
|
|
int m_x = 0;
|
|
|
|
int m_y = 0;
|
|
|
|
int m_b = 0;
|
|
|
|
|
|
|
|
/* sets up the mouse driver */
|
2024-05-29 20:11:25 +03:00
|
|
|
void mouse_init( ) {
|
|
|
|
__dpmi_regs reg;
|
|
|
|
|
|
|
|
reg.x.ax = 0;
|
|
|
|
__dpmi_int(0x33, ®);
|
|
|
|
m_state = reg.x.ax;
|
|
|
|
|
|
|
|
if (m_state) {
|
|
|
|
reg.x.ax = 10;
|
|
|
|
reg.x.bx = 0;
|
|
|
|
reg.x.cx = 0xffff;
|
|
|
|
reg.x.dx = 0x7700;
|
|
|
|
__dpmi_int(0x33, ®);
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* displays the mouse pointer */
|
2024-05-29 20:11:25 +03:00
|
|
|
void mouse_on( ) {
|
|
|
|
__dpmi_regs reg;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (m_state) {
|
|
|
|
reg.x.ax = 1;
|
|
|
|
__dpmi_int(0x33, ®);
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* hides the mouse pointer */
|
|
|
|
void mouse_off( ) {
|
|
|
|
__dpmi_regs reg;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (m_state) {
|
|
|
|
reg.x.ax = 2;
|
|
|
|
__dpmi_int(0x33, ®);
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
/* reads the mouse state */
|
2024-05-29 20:11:25 +03:00
|
|
|
void mouse_read( ) {
|
|
|
|
__dpmi_regs reg;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (m_state) {
|
|
|
|
reg.x.ax = 3;
|
|
|
|
__dpmi_int(0x33, ®);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
m_x = reg.x.cx / 8;
|
|
|
|
m_y = reg.x.dx / 8;
|
|
|
|
m_b = reg.x.bx;
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
/* sets the mouse position */
|
2024-05-29 20:11:25 +03:00
|
|
|
void mouse_move(int x, int y) {
|
|
|
|
__dpmi_regs reg;
|
|
|
|
|
|
|
|
if (m_state) {
|
|
|
|
reg.x.ax = 4;
|
|
|
|
reg.x.cx = x * 8;
|
|
|
|
reg.x.dx = y * 8;
|
|
|
|
__dpmi_int(0x33, ®);
|
|
|
|
|
|
|
|
m_x = x;
|
|
|
|
m_y = y;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* waits for a keypress or mouse button click */
|
2024-05-29 20:11:25 +03:00
|
|
|
void input_pause( ) {
|
|
|
|
mouse_on( );
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
while (m_b) mouse_read( );
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (ever) {
|
|
|
|
if (keypressed( )) {
|
|
|
|
readkey( );
|
|
|
|
break;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
mouse_read( );
|
|
|
|
if (m_b) break;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
mouse_off( );
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* sets the drawing color */
|
2024-05-29 20:11:25 +03:00
|
|
|
void text_color(int c) {
|
|
|
|
_text_color = c;
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* sets the drawing position */
|
2024-05-29 20:11:25 +03:00
|
|
|
void text_pos(int x, int y) {
|
|
|
|
_text_x = x - 1;
|
|
|
|
_text_y = y - 1;
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* prints a character */
|
2024-05-29 20:11:25 +03:00
|
|
|
void text_c(int c) {
|
|
|
|
if (_text_x < 80)
|
|
|
|
_farpokew(_dos_ds, 0xB8000 + _text_x * 2 + _text_y * 160,
|
|
|
|
c | (_text_color << 8));
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
_text_x++;
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* prints a string */
|
2024-05-29 20:11:25 +03:00
|
|
|
void text_str(char *s) {
|
|
|
|
while (*s) {
|
|
|
|
text_c((unsigned char)*s);
|
|
|
|
s++;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* prints the first part of a string */
|
2024-05-29 20:11:25 +03:00
|
|
|
void text_clamp(char *s, int max) {
|
|
|
|
int i;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if ((int)strlen(s) <= max) {
|
|
|
|
text_str(s);
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < max; i++) text_c((unsigned char)s[i]);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_str("...");
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
/* clears to the end of the current line */
|
2024-05-29 20:11:25 +03:00
|
|
|
void text_clear_eol( ) {
|
|
|
|
while (_text_x < 80) text_c(' ');
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* helper for drawing a box onto the screen */
|
2024-05-29 20:11:25 +03:00
|
|
|
void draw_box(int w, int h) {
|
|
|
|
static char url[] = "http://www.talula.demon.co.uk/freebe/";
|
|
|
|
int x, y, e;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* status text */
|
|
|
|
text_color(0x07);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(1, 1);
|
|
|
|
text_str("FreeBE/AF " FREEBE_VERSION);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
while (_text_x < 80 - (int)strlen(url)) text_c(' ');
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_str(url);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(1, screen_h - 2);
|
|
|
|
text_str("Currently installed driver:");
|
|
|
|
text_clear_eol( );
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(1, screen_h - 1);
|
|
|
|
text_str(current_driver_name);
|
|
|
|
text_clear_eol( );
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(1, screen_h);
|
|
|
|
text_str(current_driver_copyright);
|
|
|
|
text_clear_eol( );
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_color(0x74);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* top border */
|
|
|
|
text_pos(40 - w / 2 - 1, screen_h / 2 - h / 2 - 1);
|
|
|
|
text_c(TL_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (x = 0; x < w; x++) text_c(TOP_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_c(TR_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* box body */
|
|
|
|
for (y = 0; y < h; y++) {
|
|
|
|
text_pos(40 - w / 2 - 1, screen_h / 2 - h / 2 + y);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_c(SIDE_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (x = 0; x < w; x++) text_c(' ');
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_c(SIDE_CHAR);
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* bottom border */
|
|
|
|
text_pos(40 - w / 2 - 1, screen_h / 2 + (h + 1) / 2);
|
|
|
|
text_c(BL_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (x = 0; x < w; x++) text_c(TOP_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_c(BR_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* shadow */
|
|
|
|
text_color(0x08);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (y = 0; y <= h; y++) {
|
|
|
|
text_pos(41 + w / 2, screen_h / 2 - h / 2 + y);
|
|
|
|
text_c(SHADOW_CHAR);
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(40 - w / 2, screen_h / 2 + (h + 1) / 2 + 1);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (x = 0; x <= w + 1; x++) text_c(SHADOW_CHAR);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* clear the rest of the screen */
|
|
|
|
text_color(0);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (y = 2; y < screen_h / 2 - h / 2 - 1; y++) {
|
|
|
|
text_pos(1, y);
|
|
|
|
for (x = 0; x < 80; x++) text_c(' ');
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (y = screen_h / 2 + (h + 1) / 2 + 2; y < screen_h - 2; y++) {
|
|
|
|
text_pos(1, y);
|
|
|
|
for (x = 0; x < 80; x++) text_c(' ');
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (y = screen_h / 2 - h / 2 - 1; y < screen_h / 2 + (h + 1) / 2 + 2;
|
|
|
|
y++) {
|
|
|
|
e = (y == screen_h / 2 + (h + 1) / 2 + 1) ? 1 : 0;
|
|
|
|
text_pos(1, y);
|
|
|
|
for (x = 1; x < 40 - w / 2 - 1 + e; x++) text_c(' ');
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
e = (y == screen_h / 2 - h / 2 - 1) ? 1 : 0;
|
|
|
|
text_pos(42 + w / 2 - e, y);
|
|
|
|
for (x = 42 + w / 2 - e; x <= 80; x++) text_c(' ');
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_color(0x71);
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* main menu interface function */
|
2024-05-29 20:11:25 +03:00
|
|
|
int get_selection(char **str, int sel, int num, int y, int samescroll) {
|
|
|
|
static int oldscroll = 0;
|
|
|
|
int scroll;
|
|
|
|
long start, sstart;
|
|
|
|
int redraw;
|
|
|
|
int count, len;
|
|
|
|
int i, j, c, x;
|
|
|
|
int ox, oy;
|
|
|
|
int ob = 0;
|
|
|
|
|
|
|
|
count = 0;
|
|
|
|
len = 0;
|
|
|
|
|
|
|
|
while (str[count]) {
|
|
|
|
if (*str[count] <= '\002')
|
|
|
|
i = 6 + strlen(str[count] + 1);
|
|
|
|
else
|
|
|
|
i = strlen(str[count]);
|
|
|
|
|
|
|
|
if (len < i) len = i;
|
|
|
|
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count > num) {
|
|
|
|
y++;
|
|
|
|
num -= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (samescroll)
|
|
|
|
scroll = oldscroll;
|
|
|
|
else
|
|
|
|
scroll = MID(0, sel - num / 2, count - num);
|
|
|
|
|
|
|
|
len += 8;
|
|
|
|
x = 40 - len / 2;
|
|
|
|
|
|
|
|
sstart = clock( );
|
|
|
|
|
|
|
|
for (ever) {
|
|
|
|
/* draw the menu */
|
|
|
|
for (i = 0; i < num; i++) {
|
|
|
|
if (i + scroll == sel)
|
|
|
|
text_color(0x07);
|
|
|
|
else
|
|
|
|
text_color(0x70);
|
|
|
|
|
|
|
|
text_pos(x, y + i + 1);
|
|
|
|
text_str(" ");
|
|
|
|
|
|
|
|
if (*str[i + scroll] <= '\002') {
|
|
|
|
if (*str[i + scroll] == '\001') {
|
|
|
|
if (i + scroll == sel)
|
|
|
|
text_color(0x02);
|
|
|
|
else
|
|
|
|
text_color(0x72);
|
|
|
|
|
|
|
|
text_str("ON -- ");
|
|
|
|
} else {
|
|
|
|
if (i + scroll == sel)
|
|
|
|
text_color(0x04);
|
|
|
|
else
|
|
|
|
text_color(0x74);
|
|
|
|
|
|
|
|
text_str("OFF - ");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i + scroll == sel)
|
|
|
|
text_color(0x07);
|
|
|
|
else
|
|
|
|
text_color(0x70);
|
|
|
|
|
|
|
|
text_str(str[i + scroll] + 1);
|
|
|
|
|
|
|
|
for (j = strlen(str[i + scroll] + 1) + 10; j < len; j++)
|
|
|
|
text_c(' ');
|
|
|
|
} else {
|
|
|
|
text_str(str[i + scroll]);
|
|
|
|
|
|
|
|
for (j = strlen(str[i + scroll]) + 4; j < len; j++) text_c(' ');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (count > num) {
|
|
|
|
text_color(0x78);
|
|
|
|
|
|
|
|
text_pos(x + 4, y);
|
|
|
|
if (scroll > 0)
|
|
|
|
text_str("--- more ---");
|
|
|
|
else
|
|
|
|
text_str(" ");
|
|
|
|
|
|
|
|
text_pos(x + 4, y + num + 1);
|
|
|
|
if (scroll < count - num)
|
|
|
|
text_str("--- more ---");
|
|
|
|
else
|
|
|
|
text_str(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
mouse_on( );
|
|
|
|
|
|
|
|
while ((m_b) && (!ob)) mouse_read( );
|
|
|
|
|
|
|
|
redraw = FALSE;
|
|
|
|
|
|
|
|
while (!redraw) {
|
|
|
|
if (keypressed( )) {
|
|
|
|
/* deal with keyboard input */
|
|
|
|
c = readkey( );
|
|
|
|
|
|
|
|
switch (c >> 8) {
|
|
|
|
case KEY_UP:
|
|
|
|
if (sel > 0) {
|
|
|
|
sel--;
|
|
|
|
if (sel < scroll) scroll = sel;
|
|
|
|
redraw = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_DOWN:
|
|
|
|
if (sel < count - 1) {
|
|
|
|
sel++;
|
|
|
|
if (sel >= scroll + num) scroll = sel - num + 1;
|
|
|
|
redraw = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_PGUP:
|
|
|
|
if (sel > scroll) {
|
|
|
|
sel = scroll;
|
|
|
|
} else {
|
|
|
|
sel = scroll = MAX(sel - num + 1, 0);
|
|
|
|
}
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_PGDN:
|
|
|
|
if (sel < scroll + num - 1) {
|
|
|
|
sel = scroll + num - 1;
|
|
|
|
} else {
|
|
|
|
sel = MIN(sel + num - 1, count - 1);
|
|
|
|
scroll = sel - num + 1;
|
|
|
|
}
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_HOME:
|
|
|
|
sel = scroll = 0;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_END:
|
|
|
|
sel = count - 1;
|
|
|
|
scroll = count - num;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_ENTER:
|
|
|
|
case KEY_SPACE:
|
|
|
|
mouse_off( );
|
|
|
|
oldscroll = scroll;
|
|
|
|
return sel;
|
|
|
|
|
|
|
|
case KEY_ESC:
|
|
|
|
mouse_off( );
|
|
|
|
oldscroll = scroll;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* deal with mouse input */
|
|
|
|
mouse_read( );
|
|
|
|
|
|
|
|
if (m_b & 2) {
|
|
|
|
/* right button cancels */
|
|
|
|
mouse_off( );
|
|
|
|
oldscroll = scroll;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_b & 1) {
|
|
|
|
if ((m_x >= x - 1) && (m_x < x + len - 1) && (m_y >= y) &&
|
|
|
|
(m_y < y + num)) {
|
|
|
|
if (sel == m_y - y + scroll) {
|
|
|
|
/* double click detection */
|
|
|
|
start = clock( );
|
|
|
|
|
|
|
|
ox = m_x;
|
|
|
|
oy = m_y;
|
|
|
|
|
|
|
|
/* check for release */
|
|
|
|
while (((clock( ) - start) < CLOCKS_PER_SEC / 4) &&
|
|
|
|
(ox == m_x) && (oy == m_y) && (m_b & 1))
|
|
|
|
mouse_read( );
|
|
|
|
|
|
|
|
if (!(m_b & 1)) {
|
|
|
|
start = clock( );
|
|
|
|
ox = m_x;
|
|
|
|
oy = m_y;
|
|
|
|
|
|
|
|
/* check for second click */
|
|
|
|
while (
|
|
|
|
((clock( ) - start) < CLOCKS_PER_SEC / 4) &&
|
|
|
|
(ox == m_x) && (oy == m_y) && (!(m_b & 1)))
|
|
|
|
mouse_read( );
|
|
|
|
|
|
|
|
if (m_b & 1) {
|
|
|
|
/* yeah! dclick... */
|
|
|
|
mouse_off( );
|
|
|
|
oldscroll = scroll;
|
|
|
|
return sel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* left button selects */
|
|
|
|
sel = m_y - y + scroll;
|
|
|
|
redraw = TRUE;
|
|
|
|
}
|
|
|
|
} else if ((m_x >= x - 1) && (m_x < x + len - 1) &&
|
|
|
|
(m_y < y) && (scroll > 0) &&
|
|
|
|
(clock( ) > sstart + CLOCKS_PER_SEC / 24)) {
|
|
|
|
/* upward mouse scrolling */
|
|
|
|
scroll--;
|
|
|
|
sel = scroll;
|
|
|
|
redraw = TRUE;
|
|
|
|
sstart = clock( );
|
|
|
|
} else if ((m_x >= x - 1) && (m_x < x + len - 1) &&
|
|
|
|
(m_y >= y + num) && (scroll < count - num) &&
|
|
|
|
(clock( ) > sstart + CLOCKS_PER_SEC / 24)) {
|
|
|
|
/* downward mouse scrolling */
|
|
|
|
scroll++;
|
|
|
|
sel = scroll + num - 1;
|
|
|
|
redraw = TRUE;
|
|
|
|
sstart = clock( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ob = m_b;
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
2024-05-29 20:11:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mouse_off( );
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* helper to remove a string from within another string */
|
|
|
|
void strip_text(char *str, char *kill) {
|
|
|
|
char *s = strstr(str, kill);
|
|
|
|
|
|
|
|
if (s) {
|
|
|
|
if ((s > str) && (s[-1] == ' '))
|
|
|
|
strcpy(s - 1, s + strlen(kill));
|
|
|
|
else if (s[strlen(kill)] == ' ')
|
|
|
|
strcpy(s, s + strlen(kill) + 1);
|
|
|
|
else
|
|
|
|
strcpy(s, s + strlen(kill));
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* qsort() callback for sorting the driver list */
|
|
|
|
int driver_cmp(const void *q1, const void *q2) {
|
|
|
|
DRIVER_INFO *d1 = (DRIVER_INFO *)q1;
|
|
|
|
DRIVER_INFO *d2 = (DRIVER_INFO *)q2;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
return strcmp(d1->name, d2->name);
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* read the appended driver data */
|
|
|
|
int read_driver_data( ) {
|
|
|
|
typedef unsigned long (*EXT_INIT_FUNC)(AF_DRIVER * af, unsigned long id);
|
|
|
|
EXT_INIT_FUNC ext_init;
|
|
|
|
FAF_CONFIG_DATA *cfg;
|
|
|
|
AF_DRIVER *af;
|
|
|
|
DRIVER_INFO *info;
|
|
|
|
PACKFILE *f;
|
|
|
|
char name[80];
|
|
|
|
unsigned long magic;
|
|
|
|
int type, size, ret;
|
|
|
|
|
|
|
|
f = pack_fopen("#", F_READ_PACKED);
|
|
|
|
|
|
|
|
if (!f) return 1;
|
|
|
|
|
|
|
|
pack_mgetl(f);
|
|
|
|
pack_mgetl(f);
|
|
|
|
|
|
|
|
while (!pack_feof(f)) {
|
|
|
|
type = pack_mgetl(f);
|
|
|
|
|
|
|
|
if (type == DAT_FILE) {
|
|
|
|
f = pack_fopen_chunk(f, FALSE);
|
|
|
|
pack_mgetl(f);
|
|
|
|
|
|
|
|
info = &driver_info[num_drivers];
|
|
|
|
|
|
|
|
info->driver = NULL;
|
|
|
|
info->notes = NULL;
|
|
|
|
|
|
|
|
name[0] = 0;
|
|
|
|
|
|
|
|
while (!pack_feof(f)) {
|
|
|
|
type = pack_mgetl(f);
|
|
|
|
|
|
|
|
if (type == DAT_PROPERTY) {
|
|
|
|
type = pack_mgetl(f);
|
|
|
|
size = pack_mgetl(f);
|
|
|
|
|
|
|
|
if (type == DAT_NAME) {
|
|
|
|
pack_fread(name, size, f);
|
|
|
|
name[size] = 0;
|
|
|
|
} else
|
|
|
|
pack_fseek(f, size);
|
|
|
|
} else {
|
|
|
|
f = pack_fopen_chunk(f, FALSE);
|
|
|
|
|
|
|
|
if (strcmp(name, "VBEAF_DRV") == 0) {
|
|
|
|
info->driver_size = f->todo;
|
|
|
|
info->driver = malloc(info->driver_size);
|
|
|
|
pack_fread(info->driver, info->driver_size, f);
|
|
|
|
} else if (strcmp(name, "NOTES_TXT") == 0) {
|
|
|
|
info->notes_size = f->todo;
|
|
|
|
info->notes = malloc(info->notes_size);
|
|
|
|
pack_fread(info->notes, info->notes_size, f);
|
|
|
|
}
|
|
|
|
|
|
|
|
f = pack_fclose_chunk(f);
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if ((info->driver) && (info->notes)) {
|
|
|
|
strcpy(info->name, info->driver->OemVendorName);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
strip_text(info->name, "FreeBE/AF");
|
|
|
|
strip_text(info->name, "driver");
|
|
|
|
strip_text(info->name, FREEBE_VERSION);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
info->present = FALSE;
|
|
|
|
info->accel = FALSE;
|
|
|
|
info->config = 0;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
af = malloc(info->driver_size);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (af) {
|
|
|
|
memcpy(af, info->driver, info->driver_size);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (af->OemExt) {
|
|
|
|
ext_init = (EXT_INIT_FUNC)((long)af + (long)af->OemExt);
|
|
|
|
magic = ext_init(af, FAFEXT_INIT);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (((magic & 0xFFFF0000) == FAFEXT_MAGIC) &&
|
|
|
|
(isdigit((magic >> 8) & 0xFF)) &&
|
|
|
|
(isdigit(magic & 0xFF))) {
|
|
|
|
cfg = af->OemExt(af, FAFEXT_CONFIG);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (cfg) {
|
|
|
|
while (cfg->id) {
|
|
|
|
if (cfg->id == FAF_CFG_FEATURES) {
|
|
|
|
info->config =
|
|
|
|
(unsigned long)&cfg->value -
|
|
|
|
(unsigned long)af;
|
|
|
|
break;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
cfg++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
asm(" call *%2 "
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
: "=&a"(ret)
|
|
|
|
: "b"(af), "rm"(((long)af + (long)af->PlugAndPlayInit))
|
|
|
|
: "memory");
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (ret == 0) {
|
|
|
|
info->present = TRUE;
|
|
|
|
info->accel = ((af->Attributes & afHaveAccel2D) != 0);
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
free(af);
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
num_drivers++;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
f = pack_fclose_chunk(f);
|
|
|
|
} else if (type == DAT_PROPERTY) {
|
|
|
|
pack_mgetl(f);
|
|
|
|
size = pack_mgetl(f);
|
|
|
|
pack_fseek(f, size);
|
|
|
|
} else {
|
|
|
|
size = pack_mgetl(f);
|
|
|
|
pack_fseek(f, size + 4);
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
pack_fclose(f);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (num_drivers > 1)
|
|
|
|
qsort(driver_info, num_drivers, sizeof(DRIVER_INFO), driver_cmp);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* detects what VBE/AF driver is currently installed */
|
|
|
|
int check_current_driver( ) {
|
|
|
|
static char *options[] = { "Overwrite existing driver",
|
|
|
|
"Backup c:\\vbeaf.drv to c:\\vbeaf.old",
|
|
|
|
"Abort installation", NULL };
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
AF_DRIVER driver;
|
|
|
|
PACKFILE *f;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
f = pack_fopen(VBEAF_FILENAME, F_READ);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (!f) {
|
|
|
|
strcpy(current_driver_name, "{none}");
|
|
|
|
strcpy(current_driver_copyright, "");
|
|
|
|
return 0;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
pack_fread(&driver, sizeof(driver), f);
|
|
|
|
pack_fclose(f);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
strcpy(current_driver_name, driver.OemVendorName);
|
|
|
|
strcpy(current_driver_copyright, driver.OemCopyright);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (strstr(current_driver_name, "FreeBE/AF")) return 0;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
draw_box(60, 16);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(12, screen_h / 2 - 6);
|
|
|
|
text_str("Existing VBE/AF driver detected:");
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_color(0x74);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(16, screen_h / 2 - 4);
|
|
|
|
text_clamp(current_driver_name, 48);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(16, screen_h / 2 - 3);
|
|
|
|
text_clamp(current_driver_copyright, 48);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_color(0x71);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(12, screen_h / 2 - 1);
|
|
|
|
text_str("If this is one of the SciTech Display Doctor drivers,");
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(12, screen_h / 2);
|
|
|
|
text_str("it will be regenerated whenever you load UniVBE. You");
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
text_pos(12, screen_h / 2 + 1);
|
|
|
|
text_str("will need to uninstall SDD before using FreeBE/AF.");
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
switch (get_selection(options, 0, 3, screen_h / 2 + 3, FALSE)) {
|
|
|
|
case 0:
|
|
|
|
/* overwrite */
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
/* backup */
|
|
|
|
remove("c:\\vbeaf.old");
|
|
|
|
rename(VBEAF_FILENAME, "c:\\vbeaf.old");
|
|
|
|
strcpy(current_driver_name, "{none}");
|
|
|
|
strcpy(current_driver_copyright, "");
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* abort */
|
|
|
|
return 1;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* displays the readme information */
|
|
|
|
void text_viewer(char *text, int len) {
|
|
|
|
char buf[256];
|
|
|
|
int redraw;
|
|
|
|
int total, pos;
|
|
|
|
int line;
|
|
|
|
int c, i, l, p;
|
|
|
|
int oy;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
total = 1;
|
|
|
|
pos = 0;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* count number of lines */
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
if ((text[i] == '\r') || (text[i] == '\n')) {
|
|
|
|
total++;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if ((i < len - 1) && (text[i] == '\r') && (text[i + 1] == '\n'))
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
mouse_move(40, screen_h / 2);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
for (ever) {
|
|
|
|
text_color(0x70);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
p = 0;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* skip lines that we have scrolled past */
|
|
|
|
for (i = 0; i < pos; i++) {
|
|
|
|
while ((p < len) && (text[p] != '\r') && (text[p] != '\n')) p++;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if ((p < len) && (text[p] == '\r')) p++;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if ((p < len) && (text[p] == '\n')) p++;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* redraw the screen */
|
|
|
|
for (line = 1; line <= screen_h; line++) {
|
|
|
|
text_pos(1, line);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
l = 0;
|
|
|
|
|
|
|
|
while ((p < len) && (l < 255) && (text[p] != '\r') &&
|
|
|
|
(text[p] != '\n')) {
|
|
|
|
buf[l] = text[p];
|
|
|
|
|
|
|
|
if (buf[l] == '\t') {
|
|
|
|
for (i = 0; (i < 8) && (i + l < 255); i++) buf[l + i] = ' ';
|
|
|
|
l += 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
l++;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[l] = 0;
|
|
|
|
|
|
|
|
if ((p < len) && (text[p] == '\r')) p++;
|
|
|
|
|
|
|
|
if ((p < len) && (text[p] == '\n')) p++;
|
|
|
|
|
|
|
|
text_str(buf);
|
|
|
|
text_clear_eol( );
|
|
|
|
}
|
|
|
|
|
|
|
|
while (m_b) mouse_read( );
|
|
|
|
|
|
|
|
redraw = FALSE;
|
|
|
|
|
|
|
|
while (!redraw) {
|
|
|
|
if (keypressed( )) {
|
|
|
|
/* process keyboard input */
|
|
|
|
c = readkey( );
|
|
|
|
|
|
|
|
switch (c >> 8) {
|
|
|
|
case KEY_UP:
|
|
|
|
if (pos > 0) pos--;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_DOWN:
|
|
|
|
if (pos < total - screen_h) pos++;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_HOME:
|
|
|
|
pos = 0;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_END:
|
|
|
|
pos = total - screen_h;
|
|
|
|
if (pos < 0) pos = 0;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_PGUP:
|
|
|
|
pos -= screen_h - 1;
|
|
|
|
if (pos < 0) pos = 0;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_PGDN:
|
|
|
|
pos += screen_h - 1;
|
|
|
|
if (pos > total - screen_h) pos = total - screen_h;
|
|
|
|
if (pos < 0) pos = 0;
|
|
|
|
redraw = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_ESC:
|
|
|
|
case KEY_ENTER:
|
|
|
|
case KEY_SPACE: return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* process mouse input */
|
|
|
|
oy = m_y;
|
|
|
|
|
|
|
|
mouse_read( );
|
|
|
|
|
|
|
|
if (m_b) return;
|
|
|
|
|
|
|
|
if (m_y != oy) {
|
|
|
|
pos += m_y - oy;
|
|
|
|
if (pos > total - screen_h) pos = total - screen_h;
|
|
|
|
if (pos < 0) pos = 0;
|
|
|
|
mouse_move(40, screen_h / 2);
|
|
|
|
redraw = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* allows the user to edit the driver configuration */
|
|
|
|
void edit_config(unsigned long *features, unsigned long orig_features) {
|
|
|
|
static char *flist[] = { "*Linear Framebuffer",
|
|
|
|
"*Banked Framebuffer",
|
|
|
|
"*Hardware Cursor",
|
|
|
|
"*DrawScan()",
|
|
|
|
"*DrawPattScan()",
|
|
|
|
"*DrawColorPattScan()",
|
|
|
|
"*DrawScanList()",
|
|
|
|
"*DrawPattScanList()",
|
|
|
|
"*DrawColorPattScanList()",
|
|
|
|
"*DrawRect()",
|
|
|
|
"*DrawPattRect()",
|
|
|
|
"*DrawColorPattRect()",
|
|
|
|
"*DrawLine()",
|
|
|
|
"*DrawStippleLine()",
|
|
|
|
"*DrawTrap()",
|
|
|
|
"*DrawTri()",
|
|
|
|
"*DrawQuad()",
|
|
|
|
"*PutMonoImage()",
|
|
|
|
"*PutMonoImageLin()",
|
|
|
|
"*PutMonoImageBM()",
|
|
|
|
"*BitBlt()",
|
|
|
|
"*BitBltSys()",
|
|
|
|
"*BitBltLin()",
|
|
|
|
"*BitBltBM()",
|
|
|
|
"*SrcTransBlt()",
|
|
|
|
"*SrcTransBltSys()",
|
|
|
|
"*SrcTransBltLin()",
|
|
|
|
"*SrcTransBltBM()",
|
|
|
|
"Go Back",
|
|
|
|
NULL };
|
|
|
|
|
|
|
|
static int sel = 0;
|
|
|
|
int virgin = TRUE;
|
|
|
|
char *list[34];
|
|
|
|
int index[32];
|
|
|
|
int num_options, n, i;
|
|
|
|
|
|
|
|
num_options = 0;
|
|
|
|
|
|
|
|
for (n = 0; n < (int)(sizeof(flist) / sizeof(char *) - 2); n++) {
|
|
|
|
if (orig_features & (1 << n)) {
|
|
|
|
list[num_options] = flist[n];
|
|
|
|
index[num_options] = n;
|
|
|
|
num_options++;
|
|
|
|
|
|
|
|
if (*features & (1 << n))
|
|
|
|
*flist[n] = '\001';
|
|
|
|
else
|
|
|
|
*flist[n] = '\002';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
list[num_options++] = flist[n];
|
|
|
|
list[num_options] = NULL;
|
|
|
|
|
|
|
|
if (sel >= num_options) sel = 0;
|
|
|
|
|
|
|
|
n = MIN(num_options, screen_h * 4 / 7);
|
|
|
|
|
|
|
|
draw_box(40, n + 2);
|
|
|
|
|
|
|
|
for (ever) {
|
|
|
|
i = get_selection(list, sel, n, screen_h / 2 - n / 2 - 1, !virgin);
|
|
|
|
if (i >= 0) sel = i;
|
|
|
|
|
|
|
|
if ((i >= 0) && (i < num_options - 1)) {
|
|
|
|
*features ^= (1 << index[i]);
|
|
|
|
|
|
|
|
if (*features & (1 << index[i]))
|
|
|
|
*list[i] = '\001';
|
|
|
|
else
|
|
|
|
*list[i] = '\002';
|
|
|
|
} else
|
|
|
|
return;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
virgin = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* writes vbeaf.drv to c:\ */
|
|
|
|
int install_driver(DRIVER_INFO *info, unsigned long features,
|
|
|
|
unsigned long orig_features) {
|
|
|
|
PACKFILE *f;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
f = pack_fopen(VBEAF_FILENAME, F_WRITE);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (!f) {
|
|
|
|
draw_box(60, 3);
|
|
|
|
text_pos(16, screen_h / 2);
|
|
|
|
text_str("Error installing driver!");
|
|
|
|
input_pause( );
|
|
|
|
return FALSE;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (info->config)
|
|
|
|
*((unsigned long *)((unsigned long)info->driver + info->config)) =
|
|
|
|
features;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
pack_fwrite(info->driver, info->driver_size, f);
|
|
|
|
pack_fclose(f);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (info->config)
|
|
|
|
*((unsigned long *)((unsigned long)info->driver + info->config)) =
|
|
|
|
orig_features;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* installs a new driver */
|
|
|
|
int got_card(DRIVER_INFO *info) {
|
|
|
|
static char *options[] = { "View implementation notes", "Configure",
|
|
|
|
"Go Back", "Quit", NULL };
|
|
|
|
|
|
|
|
int sel = 0;
|
|
|
|
unsigned long features = 0;
|
|
|
|
unsigned long orig_features = 0;
|
|
|
|
|
|
|
|
strcpy(current_driver_name, info->driver->OemVendorName);
|
|
|
|
strcpy(current_driver_copyright, info->driver->OemCopyright);
|
|
|
|
|
|
|
|
if (info->config) {
|
|
|
|
features =
|
|
|
|
*((unsigned long *)((unsigned long)info->driver + info->config));
|
|
|
|
orig_features = features;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!install_driver(info, features, orig_features)) return FALSE;
|
|
|
|
|
|
|
|
for (ever) {
|
|
|
|
draw_box(60, 11);
|
|
|
|
|
|
|
|
text_pos(16, screen_h / 2 - 3);
|
|
|
|
text_clamp(info->driver->OemVendorName, 48);
|
|
|
|
text_pos(16, screen_h / 2 - 2);
|
|
|
|
text_str("has been installed onto your system.");
|
|
|
|
|
|
|
|
sel = get_selection(options, sel, 4, screen_h / 2, FALSE);
|
|
|
|
|
|
|
|
switch (sel) {
|
|
|
|
case 0:
|
|
|
|
/* view notes */
|
|
|
|
text_viewer(info->notes, info->notes_size);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
/* configure */
|
|
|
|
if (info->config) {
|
|
|
|
edit_config(&features, orig_features);
|
|
|
|
install_driver(info, features, orig_features);
|
|
|
|
} else {
|
|
|
|
draw_box(60, 4);
|
|
|
|
text_pos(16, screen_h / 2 - 1);
|
|
|
|
text_str("Sorry, this driver does not support the");
|
|
|
|
text_pos(16, screen_h / 2);
|
|
|
|
text_str("FreeBE/AF configuration mechanism!");
|
|
|
|
input_pause( );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
/* quit */
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* back */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* allows the user to select a driver */
|
|
|
|
int choose_card( ) {
|
|
|
|
static int sel = 0;
|
|
|
|
char *options[MAX_DRIVERS + 1];
|
|
|
|
int i, n;
|
|
|
|
|
|
|
|
for (i = 0; i < num_drivers; i++) options[i] = driver_info[i].name;
|
|
|
|
|
|
|
|
options[i] = NULL;
|
|
|
|
|
|
|
|
n = MIN(num_drivers, screen_h * 4 / 7);
|
|
|
|
|
|
|
|
draw_box(40, n + 2);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
i = get_selection(options, sel, n, screen_h / 2 - n / 2 - 1, FALSE);
|
|
|
|
|
|
|
|
if (i >= 0) {
|
|
|
|
sel = i;
|
|
|
|
return got_card(&driver_info[sel]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
|
|
|
|
/* displays the main selection menu */
|
2024-05-29 20:11:25 +03:00
|
|
|
void main_menu( ) {
|
|
|
|
static char *options[] = { "Autodetect graphics hardware",
|
|
|
|
"Manually select a driver", "Remove FreeBE/AF",
|
|
|
|
"Quit", NULL };
|
|
|
|
|
|
|
|
char old_name[80];
|
|
|
|
int sel = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (ever) {
|
|
|
|
draw_box(40, 8);
|
|
|
|
|
|
|
|
sel = get_selection(options, sel, 4, screen_h / 2 - 3, FALSE);
|
|
|
|
|
|
|
|
switch (sel) {
|
|
|
|
case 0:
|
|
|
|
/* autodetect */
|
|
|
|
for (i = 0; i < num_drivers; i++) {
|
|
|
|
if ((!strstr(driver_info[i].name, "stub implementation")) &&
|
|
|
|
(driver_info[i].present) && (driver_info[i].accel)) {
|
|
|
|
if (got_card(&driver_info[i])) return;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i >= num_drivers) {
|
|
|
|
for (i = 0; i < num_drivers; i++) {
|
|
|
|
if ((!strstr(driver_info[i].name,
|
|
|
|
"stub implementation")) &&
|
|
|
|
(driver_info[i].present) &&
|
|
|
|
(!driver_info[i].accel)) {
|
|
|
|
if (got_card(&driver_info[i])) return;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i >= num_drivers) {
|
|
|
|
draw_box(60, 3);
|
|
|
|
text_pos(16, screen_h / 2);
|
|
|
|
text_str(
|
|
|
|
"Error: unable to detect any supported hardware.");
|
|
|
|
input_pause( );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
/* manual selection */
|
|
|
|
if (choose_card( )) return;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
/* uninstall */
|
|
|
|
if (strstr(current_driver_name, "FreeBE/AF")) {
|
|
|
|
remove(VBEAF_FILENAME);
|
|
|
|
strcpy(old_name, current_driver_name);
|
|
|
|
strcpy(current_driver_name, "{none}");
|
|
|
|
strcpy(current_driver_copyright, "");
|
|
|
|
draw_box(60, 4);
|
|
|
|
text_pos(16, screen_h / 2 - 1);
|
|
|
|
text_clamp(old_name, 48);
|
|
|
|
text_pos(16, screen_h / 2);
|
|
|
|
text_str("has been removed from your system.");
|
|
|
|
input_pause( );
|
|
|
|
} else {
|
|
|
|
draw_box(60, 4);
|
|
|
|
text_pos(16, screen_h / 2 - 1);
|
|
|
|
text_str("Error removing driver:");
|
|
|
|
text_pos(16, screen_h / 2);
|
|
|
|
text_str("No FreeBE/AF driver is currently installed!");
|
|
|
|
input_pause( );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* quit */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2024-05-29 19:55:33 +03:00
|
|
|
}
|
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
/* main program */
|
|
|
|
int main( ) {
|
|
|
|
struct text_info info;
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
allegro_init( );
|
|
|
|
install_keyboard( );
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
if (read_driver_data( ) != 0) {
|
|
|
|
printf("Fatal error: driver data not present!\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
__djgpp_set_ctrl_c(0);
|
|
|
|
setcbrk(0);
|
2024-05-29 19:55:33 +03:00
|
|
|
|
2024-05-29 20:11:25 +03:00
|
|
|
gettextinfo(&info);
|
|
|
|
screen_h = info.screenheight;
|
|
|
|
_setcursortype(_NOCURSOR);
|
|
|
|
|
|
|
|
mouse_init( );
|
|
|
|
|
|
|
|
if (check_current_driver( ) == 0) main_menu( );
|
|
|
|
|
|
|
|
clrscr( );
|
|
|
|
_setcursortype(_NORMALCURSOR);
|
|
|
|
|
|
|
|
if (strcmp(current_driver_name, "{none}") == 0) {
|
|
|
|
textattr(0x04);
|
|
|
|
cputs("No VBE/AF driver is installed on your machine.");
|
|
|
|
} else {
|
|
|
|
textattr(0x07);
|
|
|
|
cputs("Installed driver:\r\n\r\n");
|
|
|
|
textattr(0x02);
|
|
|
|
cputs(current_driver_name);
|
|
|
|
cputs("\r\n");
|
|
|
|
cputs(current_driver_copyright);
|
|
|
|
}
|
|
|
|
|
|
|
|
textattr(0x07);
|
|
|
|
cputs("\r\n\r\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|