mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-02-05 15:55:26 +00:00
git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/personal/carm/dev-1.0@255 6778bc44-b910-0410-a7a0-be141de4315d
1029 lines
29 KiB
C++
Executable File
1029 lines
29 KiB
C++
Executable File
/**
|
|
* projectM -- Milkdrop-esque visualisation SDK
|
|
* Copyright (C)2003-2004 projectM Team
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
* See 'LICENSE.txt' included within this release
|
|
*
|
|
*/
|
|
/**
|
|
* $Id: glConsole.c,v 1.2 2005/12/28 18:51:18 psperl Exp $
|
|
*
|
|
* Encapsulation of an OpenGL-based console
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#ifdef MACOS
|
|
#include <unistd.h>
|
|
#endif /** MACOS */
|
|
#include <time.h>
|
|
|
|
#include "projectM.hpp"
|
|
|
|
#ifdef MACOS
|
|
#include <gl.h>
|
|
#else
|
|
#include <GL/gl.h>
|
|
#endif /** MACOS */
|
|
#include "glConsole.h"
|
|
#include "Common.hpp"
|
|
#include "fatal.h"
|
|
|
|
#include "wipemalloc.h"
|
|
|
|
#ifdef USE_FTGL
|
|
#include <FTGL/FTGL.h>
|
|
#include <FTGL/FTGLPixmapFont.h>
|
|
#endif /** USE_FTGL */
|
|
|
|
#define HEIGHT_SPACE 8 /* pixel space between lines */
|
|
#define DEFAULT_CONSOLE_FOREGROUND_COLOR CONSOLE_WHITE
|
|
#define DEFAULT_CONSOLE_BACKGROUND_COLOR CONSOLE_BLACK
|
|
#define DEFAULT_CURSOR_COLOR CONSOLE_GREEN
|
|
#define CURSOR_REFRESH_RATE 10
|
|
|
|
static int gl_console_set_color(color_t color);
|
|
int clear_console_screen_buffer(gl_console_t * gl_console);
|
|
int clear_console_scroll_buffer(gl_console_t * gl_console);
|
|
//float screen_width = 800;
|
|
//float screen_height = 600;
|
|
|
|
extern projectM *PM;
|
|
int refresh_count = 0;
|
|
|
|
/* Creates a new console of (width X height) with left corner at
|
|
(x, y) */
|
|
gl_console_t * glConsoleCreate(int screen_width, int screen_height, int scroll_width, int scroll_height,
|
|
float start_x, float start_y, int Font_Descriptor) {
|
|
|
|
console_char_t * buffer;
|
|
gl_console_t * gl_console;
|
|
|
|
if ((screen_width > MAX_CONSOLE_WIDTH) || (screen_width < 1))
|
|
return NULL;
|
|
|
|
if ((screen_height > MAX_CONSOLE_HEIGHT) || (screen_height < 1))
|
|
return NULL;
|
|
|
|
if ((gl_console = (gl_console_t*)wipemalloc(sizeof(gl_console_t))) == NULL)
|
|
return NULL;
|
|
|
|
if ((scroll_height < screen_height))
|
|
return NULL;
|
|
|
|
if ((scroll_width < screen_width))
|
|
return NULL;
|
|
|
|
if ((buffer = (console_char_t*)wipemalloc(scroll_width*scroll_height*sizeof(console_char_t))) == NULL)
|
|
return NULL;
|
|
/* Need to know height and width of screen so we can see if the
|
|
if x and y are valid, will do later */
|
|
|
|
/* Set struct parameters */
|
|
gl_console->screen_buffer = buffer;
|
|
gl_console->font_descriptor = Font_Descriptor;
|
|
gl_console->screen_width = screen_width;
|
|
gl_console->screen_height = screen_height;
|
|
gl_console->scroll_width = scroll_width;
|
|
gl_console->scroll_height = scroll_height;
|
|
gl_console->start_x = start_x; /* x coordinate of console's upper left corner */
|
|
gl_console->start_y = start_y; /* y coordinate of console's upper left corner */
|
|
gl_console->screen_start_x = gl_console->screen_start_y = 0;
|
|
gl_console->screen_x = gl_console->screen_y = 0; /* set cursor positions to zero */
|
|
gl_console->cursor_ptr = buffer; /* start cursor pointer at beginning of buffer */
|
|
gl_console->current_fg = DEFAULT_CONSOLE_FOREGROUND_COLOR;
|
|
gl_console->current_bg = DEFAULT_CONSOLE_BACKGROUND_COLOR;
|
|
gl_console->scroll_buffer = buffer;
|
|
gl_console->cursor_color = DEFAULT_CURSOR_COLOR;
|
|
gl_console->cursor_style = BAR_STYLE;
|
|
gl_console->flags = 0;
|
|
/* Clears the console buffer */
|
|
clear_console_scroll_buffer(gl_console);
|
|
|
|
if (GL_CONSOLE_DEBUG) printf("glConsoleCreate: finished initializing\n");
|
|
|
|
/* Finished, return new console */
|
|
return gl_console;
|
|
}
|
|
|
|
/* Destroy the passed console */
|
|
int glConsoleDestroy(gl_console_t * console) {
|
|
|
|
if (console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
free(console->scroll_buffer);
|
|
free(console);
|
|
|
|
console = NULL;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
int glConsoleClearScreen(gl_console_t * console) {
|
|
|
|
if (console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
clear_console_screen_buffer(console);
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
|
|
int glConsoleClearBuffer(gl_console_t * console) {
|
|
|
|
if (console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
clear_console_scroll_buffer(console);
|
|
glConsoleAlignCursorLeft(console);
|
|
glConsoleAlignCursorUp(console);
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Aligns cursor to the next character 'c' */
|
|
int glConsoleCursorToNextChar(char c, gl_console_t * gl_console) {
|
|
|
|
console_char_t * endofbuf;
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
endofbuf = gl_console->scroll_buffer + (gl_console->scroll_width*gl_console->scroll_height) - 1;
|
|
|
|
while ((gl_console->cursor_ptr != endofbuf) && (gl_console->cursor_ptr->symbol != c))
|
|
glConsoleMoveCursorForward(gl_console);
|
|
|
|
return PROJECTM_SUCCESS;
|
|
|
|
}
|
|
|
|
int glConsoleMoveCursorUp(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* The screen buffer is at the top and so is the screen cursor */
|
|
if ((gl_console->screen_start_y == 0) && (gl_console->screen_y == 0)) {
|
|
|
|
/* Wrap up flag specified, move cursor to bottom of screen */
|
|
if (gl_console->flags & CONSOLE_FLAG_SCROLL_WRAP_UP) {
|
|
glConsoleAlignCursorDown(gl_console);
|
|
}
|
|
|
|
|
|
/* Do nothing instead */
|
|
|
|
}
|
|
/* The screen cursor is at the top but not the screen buffer */
|
|
else if (gl_console->screen_y == 0){
|
|
|
|
/* screen_y stays the same, since it scrolls up one */
|
|
|
|
/* Decrement the cursor_ptr by one line */
|
|
gl_console->cursor_ptr -= gl_console->scroll_width;
|
|
|
|
/* Decrement starting 'y' position of the screen buffer */
|
|
gl_console->screen_start_y--;
|
|
|
|
/* Decrement the screen buffer by one line */
|
|
gl_console->screen_buffer -= gl_console->scroll_width;
|
|
|
|
|
|
}
|
|
/* General case, not at top or bottoom */
|
|
else {
|
|
gl_console->screen_y--;
|
|
gl_console->cursor_ptr -= gl_console->scroll_width;
|
|
}
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
|
|
int glConsoleMoveCursorDown(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* The screen buffer is at the bottom and so is the screen cursor, this may not ever
|
|
happen */
|
|
if (gl_console->screen_start_y == (gl_console->scroll_height - gl_console->screen_height)) {
|
|
if (gl_console->screen_y == (gl_console->screen_height - 1)) {
|
|
// printf("BOTTOM AND END\n");
|
|
/* Wrap down to up enabled */
|
|
if (gl_console->flags & CONSOLE_FLAG_SCROLL_WRAP_DOWN) {
|
|
glConsoleAlignCursorUp(gl_console);
|
|
}
|
|
|
|
/* Otherwise, do nothing */
|
|
}
|
|
}
|
|
|
|
/* The screen cursor is at the bottom but not the end of the scroll buffer */
|
|
else if (gl_console->screen_y == (gl_console->screen_height - 1)) {
|
|
|
|
// printf("BOTTOM BUT NOT END\n");
|
|
/* screen_y stays the same, since it scrolls down one */
|
|
|
|
/* Increment the cursor_ptr by one line */
|
|
gl_console->cursor_ptr += gl_console->scroll_width;
|
|
|
|
/* Increment starting 'y' position of the screen buffer */
|
|
gl_console->screen_start_y++;
|
|
|
|
/* Increment the screen buffer by one line */
|
|
gl_console->screen_buffer += gl_console->scroll_width;
|
|
|
|
|
|
}
|
|
|
|
/* General case, not at top or bottoom */
|
|
else {
|
|
// printf("GENERAL CASE\n");
|
|
gl_console->screen_y++;
|
|
gl_console->cursor_ptr += gl_console->scroll_width;
|
|
}
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Move the console forward one character, wrap around is the current behavior */
|
|
int glConsoleMoveCursorForward(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
|
|
/* The case where the end of the screen is reached and the end of the scroll buffer */
|
|
if ((gl_console->screen_start_x + gl_console->screen_width) == (gl_console->scroll_width)) {
|
|
if ((gl_console->screen_x) == (gl_console->screen_width - 1)) {
|
|
|
|
/* Wrap around to next line if this flag is enabled */
|
|
if (gl_console->flags & CONSOLE_FLAG_SCROLL_WRAP_RIGHT) {
|
|
/* Down one and to the left */
|
|
glConsoleMoveCursorDown(gl_console);
|
|
glConsoleAlignCursorLeft(gl_console);
|
|
}
|
|
|
|
/* Otherwise do nothing */
|
|
}
|
|
}
|
|
|
|
/* The case where the end of the screen is reach, but the not end of the scroll buffer */
|
|
else if (gl_console->screen_x == (gl_console->screen_width - 1)) {
|
|
|
|
/* screen_x doesn't change because the whole console is shifted left */
|
|
/* screen_y doesn't change because we haven't reached the end of the scroll buffer */
|
|
|
|
gl_console->cursor_ptr++; /* increment cursor pointer */
|
|
gl_console->screen_buffer++; /* move the screen buffer right one */
|
|
gl_console->screen_start_x++; /* incrementing the start of the screen 'x' variable */
|
|
}
|
|
|
|
/* The most common case, no scrolling required. In other words, the cursor is at some
|
|
arbitrary non end point position */
|
|
else {
|
|
gl_console->screen_x++; /* increment x variable */
|
|
gl_console->cursor_ptr++; /* increment cursor pointer */
|
|
}
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
|
|
/* Moves the cursor backward one space */
|
|
int glConsoleMoveCursorBackward(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* The case where the beginning of the screen is reached and the beginning of the scroll buffer */
|
|
if ((gl_console->screen_start_x == 0) && (gl_console->screen_x == 0)) {
|
|
if (gl_console->flags & CONSOLE_FLAG_SCROLL_WRAP_LEFT) {
|
|
glConsoleMoveCursorUp(gl_console);
|
|
glConsoleAlignCursorRight(gl_console);
|
|
}
|
|
|
|
}
|
|
|
|
/* The case where the beginning of the screen is reach, but the not beginning of the scroll buffer */
|
|
else if (gl_console->screen_x == 0) {
|
|
gl_console->cursor_ptr--; /* decrement cursor pointer */
|
|
gl_console->screen_buffer--; /* move the screen buffer left one */
|
|
gl_console->screen_start_x--; /* decrement the start of the screen 'x' variable */
|
|
}
|
|
|
|
/* The most common case, no scrolling required. In other words, the cursor is at some
|
|
arbitrary non end point position */
|
|
else {
|
|
gl_console->screen_x--; /* increment x variable */
|
|
gl_console->cursor_ptr--; /* increment cursor pointer */
|
|
}
|
|
|
|
/* Finised, return success */
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Sets the cursor position to (x,y) of the passed console */
|
|
int glConsoleSetCursorPos(int x, int y, gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Bound checks */
|
|
if ((x < 0) || (x > (gl_console->scroll_width-1)))
|
|
return PROJECTM_FAILURE;
|
|
|
|
if ((y < 0) || (y > (gl_console->scroll_height-1)))
|
|
return PROJECTM_FAILURE;
|
|
|
|
|
|
/* Set cursor ptr to new screen location. This variable does not depend on if the
|
|
screen needs to be scrolled */
|
|
gl_console->cursor_ptr = gl_console->scroll_buffer + (y * gl_console->scroll_width) + x;
|
|
|
|
/* Goal 1: Determine what needs to be changed on the X axis */
|
|
|
|
|
|
/* Case (i): x coordinate is less than the starting screen buffer x coordinate. Must
|
|
shift the screen buffer left by difference of the two coordinates */
|
|
if (x < gl_console->screen_start_x) {
|
|
// printf("X: case (i)\n");
|
|
|
|
/* Align x offset to new x corodinate */
|
|
gl_console->screen_start_x = x;
|
|
|
|
/* Set screen_x to zero because we are left edge aligned in the screen buffer */
|
|
gl_console->screen_x = 0;
|
|
|
|
}
|
|
|
|
/* Case (ii): x coordinate is greater than farthest screen buffer x coordinate. Must
|
|
shift the screen buffer right by difference of the two coordinates */
|
|
else if (x > (gl_console->screen_start_x+gl_console->screen_width-1)) {
|
|
// printf("X: case (ii)\n");
|
|
|
|
/* Align end of screen buffer X coordinate space to new x coordinate */
|
|
gl_console->screen_start_x = x - (gl_console->screen_width - 1);
|
|
|
|
/* Set screen_x to right edge of screen buffer because we are right aligned to the new x coordinate */
|
|
gl_console->screen_x = gl_console->screen_width - 1;
|
|
}
|
|
|
|
/* CASE (iii): x coordinate must lie within the current screen buffer rectangle. No need to
|
|
shift the screen buffer on the X axis */
|
|
else {
|
|
// printf("X: case (iii)\n");
|
|
|
|
/* Set the new screen coordinate to the passed in x coordinate minus the starting screen buffer distance */
|
|
gl_console->screen_x = x - gl_console->screen_start_x;
|
|
|
|
}
|
|
|
|
|
|
/* Goal 2: Determine what needs to be changed on the Y axis */
|
|
|
|
/* Case (i): y coordinate is less than the starting screen buffer y coordinate. Must
|
|
shift the screen buffer up by difference of the two coordinates */
|
|
if (y < gl_console->screen_start_y) {
|
|
// printf("Y: case (i) y = %d, start_y = %d\n", y, gl_console->screen_start_y);
|
|
|
|
/* Align y offset to new y corodinate */
|
|
gl_console->screen_start_y = y;
|
|
|
|
/* Set screen_y to zero because we are top aligned in the screen buffer */
|
|
gl_console->screen_y = 0;
|
|
|
|
}
|
|
|
|
/* Case (ii): y coordinate is greater than loweest screen buffer y coordinate. Must
|
|
shift the screen buffer down by difference of the two coordinates */
|
|
else if (y > (gl_console->screen_start_y+gl_console->screen_height-1)) {
|
|
// printf("Y: case (ii)\n");
|
|
|
|
/* Align end of screen buffer Y coordinate space to new y coordinate */
|
|
gl_console->screen_start_y = y - (gl_console->screen_height-1);
|
|
|
|
/* Set screen_y to bottom edge of screen buffer because we are bottom aligned to the new y coordinate */
|
|
gl_console->screen_y = gl_console->screen_height - 1;
|
|
}
|
|
|
|
/* CASE (iii): y coordinate must lie within the current screen buffer rectangle. No need to
|
|
shift the screen buffer on the Y axis */
|
|
|
|
else {
|
|
// printf("Y: case (iii)\n");
|
|
/* Set the new screen coordinate to the passed in y coordinate minus the starting screen buffer distance */
|
|
gl_console->screen_y = y - gl_console->screen_start_y;
|
|
|
|
}
|
|
|
|
|
|
/* Re-adjust screen buffer ptr based on computed screen starting coordinates */
|
|
gl_console->screen_buffer = gl_console->scroll_buffer + (gl_console->screen_start_y*gl_console->screen_width)
|
|
+ gl_console->screen_start_x;
|
|
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Sets 'x' and 'y' to the console coordinates of the current cursor position */
|
|
int glConsoleGetCursorPos(int * x, int * y, gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Null arguments passed, bail */
|
|
if ((x == NULL) || (y == NULL))
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Set coordinates with appropiate offset */
|
|
*x = gl_console->screen_x + gl_console->screen_start_x;
|
|
*y = gl_console->screen_y + gl_console->screen_start_y;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Helper function that changes the current color */
|
|
static int gl_console_set_color(color_t color) {
|
|
|
|
switch (color) {
|
|
|
|
case CONSOLE_BLACK:
|
|
glColor4f(0, 0, 0, 1);
|
|
break;
|
|
case CONSOLE_RED:
|
|
glColor4f(1, 0, 0, 1);
|
|
break;
|
|
case CONSOLE_GREEN:
|
|
glColor4f(0, 1, 0, 1);
|
|
break;
|
|
case CONSOLE_WHITE:
|
|
glColor4f(1, 1, 1, 1);
|
|
break;
|
|
case CONSOLE_BLUE:
|
|
glColor4f(0, 0, 1, 1);
|
|
break;
|
|
case CONSOLE_TRANS:
|
|
glColor4f(0, 0, 0, 0);
|
|
break;
|
|
default: /* hmm, use white I guess */
|
|
glColor4f(1, 1, 1, 1);
|
|
}
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Sets the passed console to a new foreground */
|
|
int glConsoleSetFGColor(color_t color, gl_console_t * gl_console) {
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
gl_console->current_fg = color;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Sets the passed console to a new background */
|
|
int glConsoleSetBGColor(color_t color, gl_console_t * gl_console) {
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
gl_console->current_bg = color;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Sets the cursor color */
|
|
int glConsoleSetCursorColor(color_t color, gl_console_t * gl_console) {
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
gl_console->cursor_color = color;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Prints a string starting from the current cursor position */
|
|
int glConsolePrintString(char * s, gl_console_t * gl_console) {
|
|
|
|
int len;
|
|
int i;
|
|
console_char_t console_char;
|
|
char symbol;
|
|
|
|
/* Null argument checks */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
if (s == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Set the console struct to correct fg and bg values.
|
|
The character value will change in the for loop */
|
|
console_char.fg_color = gl_console->current_fg;
|
|
console_char.bg_color = gl_console->current_bg;
|
|
console_char.symbol = 0;
|
|
|
|
/* Calculate length of the string */
|
|
len = strlen(s);
|
|
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
/* Case on the type of character */
|
|
|
|
switch (symbol = *(s+i)) {
|
|
|
|
case '\r':
|
|
case '\n':
|
|
console_char.symbol = symbol;
|
|
*gl_console->cursor_ptr = console_char;
|
|
glConsoleMoveCursorDown(gl_console);
|
|
glConsoleAlignCursorLeft(gl_console);
|
|
break;
|
|
case '\b':
|
|
glConsoleMoveCursorBackward(gl_console);
|
|
break;
|
|
default:
|
|
/* Change the screen_buffer value */
|
|
console_char.symbol = symbol;
|
|
*gl_console->cursor_ptr = console_char;
|
|
glConsoleMoveCursorForward(gl_console);
|
|
|
|
}
|
|
}
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
|
|
/* Clears the console screen_buffer, using current fg and bg values */
|
|
int clear_console_screen_buffer(gl_console_t * gl_console) {
|
|
|
|
int i, console_size;
|
|
console_char_t console_char;
|
|
|
|
/* Set console struct to current fg and bg values */
|
|
console_char.fg_color = gl_console->current_fg;
|
|
console_char.bg_color = gl_console->current_bg;
|
|
console_char.symbol = 0; /* empty symbol */
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
console_size = gl_console->scroll_width * gl_console->scroll_height;
|
|
|
|
for (i = 0; i < console_size; i++)
|
|
*(gl_console->screen_buffer + i) = console_char;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Clears the entire buffer */
|
|
int clear_console_scroll_buffer(gl_console_t * gl_console) {
|
|
|
|
int i, console_size;
|
|
console_char_t console_char;
|
|
|
|
/* Set console struct to current fg and bg values */
|
|
console_char.fg_color = gl_console->current_fg;
|
|
console_char.bg_color = gl_console->current_bg;
|
|
console_char.symbol = 0; /* empty symbol */
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
console_size = gl_console->scroll_width * gl_console->scroll_height;
|
|
|
|
for (i = 0; i < console_size; i++)
|
|
*(gl_console->scroll_buffer + i) = console_char;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Align the cursor all the way to the right of the passed console */
|
|
int glConsoleAlignCursorRight(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Set the cursor pointer to the rightmost end of the scroll buffer */
|
|
gl_console->cursor_ptr += gl_console->scroll_width - (gl_console->screen_start_x + gl_console->screen_x) - 1;
|
|
|
|
/* Move the screen buffer to the farthest right as possible */
|
|
gl_console->screen_buffer += gl_console->scroll_width - gl_console->screen_start_x - gl_console->screen_width;
|
|
|
|
/* Set the screen start 'x' value to length of the scroll buffer minus the length
|
|
of the screen buffer with a -1 offset to access the array correctly */
|
|
gl_console->screen_start_x = gl_console->scroll_width - gl_console->screen_width;
|
|
|
|
/* Set the screen_x cursor value to the screen width length minus an array adjustment offset */
|
|
gl_console->screen_x = gl_console->screen_width - 1;
|
|
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Align the cursor all the way to the right of the passed console */
|
|
int glConsoleAlignCursorLeft(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Set the cursor pointer to the left most end of the scroll buffer */
|
|
gl_console->cursor_ptr -= (gl_console->screen_start_x + gl_console->screen_x);
|
|
|
|
/* Set the screen buffer all the way to left */
|
|
gl_console->screen_buffer -= gl_console->screen_start_x;
|
|
|
|
/* Set the screen start x to the leftmost end of the scroll buffer */
|
|
gl_console->screen_start_x = 0;
|
|
|
|
/* Set the screen_x cursor value to the leftmost end of the screne buffer */
|
|
gl_console->screen_x = 0;
|
|
|
|
|
|
/* Finished, return success */
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Align the cursor to the top of the screen of the passed console */
|
|
int glConsoleAlignCursorUp(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Set the cursor pointer to the top of the buffer plus the x offset */
|
|
gl_console->cursor_ptr = gl_console->scroll_buffer + gl_console->screen_start_x + gl_console->screen_x;
|
|
|
|
/* Set the screen start y to the top of the scroll buffer */
|
|
gl_console->screen_start_y = 0;
|
|
|
|
/* Set the screen_y cursor value to the top of the screen buffer */
|
|
gl_console->screen_y = 0;
|
|
|
|
/* Set screen buffer to the top shifted lefted by the screen start value */
|
|
gl_console->screen_buffer = gl_console->scroll_buffer + gl_console->screen_start_x;
|
|
|
|
/* Finished, return success */
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
|
|
/* Align the cursor to the top of the screen of the passed console */
|
|
int glConsoleAlignCursorDown(gl_console_t * gl_console) {
|
|
|
|
/* Null argument check */
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Set the cursor pointer to the bottom of the buffer plus the x offset */
|
|
gl_console->cursor_ptr = gl_console->scroll_buffer +
|
|
((gl_console->scroll_height-1)*gl_console->scroll_width)
|
|
+ gl_console->screen_start_x + gl_console->screen_x;
|
|
|
|
/* Set the screen start y to the bottom of the scroll buffer mi screen_height */
|
|
gl_console->screen_start_y = gl_console->scroll_height - gl_console->screen_height;
|
|
|
|
/* Set the screen_y cursor value to the bottom of the screen buffer */
|
|
gl_console->screen_y = gl_console->screen_height - 1;
|
|
|
|
/* Set screen buffer to the bottom minus the height of the screen
|
|
shifted left by the screen start value */
|
|
|
|
gl_console->screen_buffer = gl_console->scroll_buffer +
|
|
((gl_console->scroll_height - gl_console->screen_height)
|
|
*gl_console->scroll_width) + gl_console->screen_start_x;
|
|
|
|
/* Finished, return success */
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
int glConsoleDraw( gl_console_t * console) {
|
|
|
|
#ifdef USE_FTGL
|
|
int vw = 512;
|
|
int vh=512;
|
|
int x,y;
|
|
//float minx, miny, maxx, maxy;
|
|
char * symbol;
|
|
console_char_t * console_char;
|
|
float start_x, start_y;
|
|
|
|
//REMOVE SOON
|
|
//int width=800,height=600;
|
|
|
|
|
|
// console->start_x=0;
|
|
// console->start_y=1;
|
|
|
|
|
|
int width=1;
|
|
int height=1;
|
|
|
|
|
|
|
|
start_y = -(console->start_y - 1.0);
|
|
start_x = console->start_x;
|
|
|
|
/* Null argument check */
|
|
if (console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
symbol = (char*)wipemalloc(sizeof(char)+1);
|
|
*symbol = *(symbol+1) = 0;
|
|
|
|
/* First, push the gl matrix to save data */
|
|
glPushMatrix();
|
|
|
|
|
|
/* Start rendering at the console's start position */
|
|
glTranslatef(start_x,start_y,-1);
|
|
//glTranslatef(0,0.5,-1);
|
|
/* Assign a pointer to the start of the console buffer */
|
|
console_char = console->screen_buffer;
|
|
|
|
/* Iterate through entire console buffer, drawing each
|
|
character one at a time with appropiate foreground and
|
|
background values. May not be the most efficient. */
|
|
|
|
// glScalef(8.0,8.0,0);
|
|
|
|
|
|
|
|
float llx; // The bottom left near most ?? in the x axis
|
|
float lly; // The bottom left near most ?? in the y axis
|
|
float llz; // The bottom left near most ?? in the z axis
|
|
float urx; // The top right far most ?? in the x axis
|
|
float ury; // The top right far most ?? in the y axis
|
|
float urz; // The top right far most ?? in the z axis
|
|
float advance;
|
|
|
|
|
|
//Figure out size of one console unit
|
|
PM->renderer->other_font->FaceSize((unsigned)(16*(vh/512.0)));
|
|
|
|
/// @bug commented out to get projectM working
|
|
//advance=PM->renderer->other_font->Advance("W");
|
|
PM->renderer->other_font->BBox("qpg_XT[",llx,lly,llx,urx,ury,urz);
|
|
|
|
|
|
float invfix=1.0/512;
|
|
llx*=invfix;lly*=invfix;llz*=invfix;
|
|
urx*=invfix;ury*=invfix;urz*=invfix;
|
|
advance=advance/vw;
|
|
|
|
glTranslatef(advance*0.5,lly-ury,0);
|
|
|
|
for (y = 0; y < console->screen_height; y++) {
|
|
|
|
glPushMatrix();
|
|
char buffer[console->screen_width+1];
|
|
memset( buffer, '\0',sizeof(char) * (console->screen_width+1));
|
|
|
|
|
|
|
|
for (x = 0; x < console->screen_width; x++) {
|
|
|
|
console_char = console->screen_buffer + (y*console->scroll_width) + x;
|
|
*symbol = console_char->symbol;
|
|
|
|
|
|
/* Draw the background color */
|
|
if ((console->flags & CONSOLE_FLAG_ALWAYS_DRAW_BACKGROUND) || (*symbol != 0)) {
|
|
|
|
/* Draw the background by drawing a rectangle */
|
|
gl_console_set_color(console_char->bg_color);
|
|
glRectf(llx, lly ,llx+advance, ury);
|
|
|
|
}
|
|
|
|
/* We are at the cursor position. See if the cursor is hidden or not and act accordingly */
|
|
if ((console_char == console->cursor_ptr) && (!(console->flags & CONSOLE_FLAG_CURSOR_HIDDEN))) {
|
|
|
|
/* Cursor is not hidden and blinking */
|
|
if (console->flags & CONSOLE_FLAG_CURSOR_BLINKING) {
|
|
if (refresh_count % CURSOR_REFRESH_RATE)
|
|
gl_console_set_color(console->cursor_color);
|
|
else
|
|
gl_console_set_color(console_char->bg_color);
|
|
}
|
|
|
|
/* Cursor is not hidden, and not blinking */
|
|
else {
|
|
gl_console_set_color(console->cursor_color);
|
|
}
|
|
|
|
/* Draw the cursor according to the set style */
|
|
if (console->cursor_style == BAR_STYLE)
|
|
glRectf(llx, lly, llx+advance, ury);
|
|
else if (console->cursor_style == UNDERLINE_STYLE) {
|
|
glRectf(llx, lly, llx+advance, ury);
|
|
}
|
|
}
|
|
|
|
/* The cursor is not here or hidden, draw regular background (OLD COMMENT) */
|
|
|
|
/* Instead of the above, do nothing because we always draw the background before
|
|
printing the cursor to the screen */
|
|
else {
|
|
|
|
// if ((console->flags & CONSOLE_FLAG_ALWAYS_DRAW_BACKGROUND) || (*symbol != 0)) {
|
|
|
|
/* Draw the background by drawing a rectangle */
|
|
// gl_console_set_color(console_char->bg_color);
|
|
// glRectf(-0.5, 1.0 ,1.0, -1.0);
|
|
|
|
//}
|
|
}
|
|
|
|
/* If the symbol is nonzero draw it */
|
|
if (*symbol != 0 && *symbol != '\n') {
|
|
buffer[x]=*symbol;
|
|
//gl_console_set_color(console_char->fg_color);
|
|
}
|
|
/* Now shift to the right by the size of the character space */
|
|
glTranslatef(advance,0,0);
|
|
|
|
// console_char++;
|
|
}
|
|
|
|
|
|
// glColor4f(0.0,1.0,1.0,1.0);
|
|
//glTranslatef(((lly-ury)*console->screen_width),0,0);
|
|
//glRasterPos2f(50,-50);
|
|
|
|
glPopMatrix();
|
|
|
|
console_char = console->screen_buffer + (y*console->scroll_width + 1);
|
|
gl_console_set_color(console_char->fg_color);
|
|
glRasterPos2f(0,0);
|
|
|
|
PM->renderer->other_font->Render(buffer);
|
|
|
|
|
|
/* New line, shift down the size of the symbol plus some extra space */
|
|
|
|
|
|
glTranslatef(0,(lly-ury), 0);
|
|
}
|
|
//glColor4f(1,1,1,1);
|
|
|
|
/* Finished, pop the gl matrix and return success */
|
|
glPopMatrix();
|
|
|
|
|
|
free(symbol);
|
|
refresh_count++;
|
|
#endif /** USE_FTGL */
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
int glConsoleSetFlags(int flags, gl_console_t * gl_console) {
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
gl_console->flags = gl_console->flags | flags;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
#ifdef NOGOOD
|
|
int glConsoleStartShell(gl_console_t * gl_console) {
|
|
|
|
int pid1, pid2;
|
|
char * s;
|
|
char c;
|
|
FILE * fs;
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
if ((s = wipemalloc(sizeof(char) + 512)) == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
memset(s, 0, 512);
|
|
|
|
#if !defined(MACOS) && !defined(WIN32)
|
|
if ((pid1 = fork()) == 0) {
|
|
printf("bash starting\n");
|
|
execve("/bin/bash", NULL, NULL);
|
|
printf("bash exiting..\n");
|
|
exit(0);
|
|
}
|
|
|
|
if ((pid2 = fork()) == 0) {
|
|
//fs = fopen("tempfile", "r");
|
|
printf("about to loop on stdout\n");
|
|
while (1) {
|
|
//printf("^");//fflush(stdout);
|
|
//ungetc(c, stdin);
|
|
fread(s, 1, 1, stdout);
|
|
*s = 'a';
|
|
//printf("%c", *s);fflush(stdout);
|
|
glConsolePrintString(s, gl_console);
|
|
}
|
|
//fclose(fs);
|
|
printf("waiting for pid1 to exit\n");
|
|
waitpid(pid1, NULL, 0);
|
|
free(s);
|
|
printf("pid1 exited\n");
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
printf("bash should have started\n");
|
|
#endif /** !MACOS */
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
#endif
|
|
/* Copies the console buffer into a character array */
|
|
int glConsoleCopyBuffer(char * src, int len, gl_console_t * gl_console) {
|
|
|
|
int i;
|
|
int j = 0;
|
|
int size;
|
|
char c;
|
|
if (src == NULL)
|
|
return PROJECTM_FAILURE;
|
|
if (len < 0)
|
|
return PROJECTM_FAILURE;
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
/* Clear the character space */
|
|
memset(src, 0, len);
|
|
|
|
size = gl_console->scroll_width*gl_console->scroll_height;
|
|
|
|
for (i=0; ((i - j) < len) && (i < size); i++) {
|
|
c = (gl_console->scroll_buffer + i)->symbol;
|
|
|
|
/* We don't want to accidentally null terminate the string...*/
|
|
if (c != 0)
|
|
src[i - j] = c;
|
|
else
|
|
j++;
|
|
|
|
// if (c != 0)
|
|
// src[i] = c;
|
|
// else
|
|
// src[i] = '\n';
|
|
}
|
|
|
|
/* Ensure the string actually ends */
|
|
src[len - 1] = 0;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|
|
/* Sets the cursor draw style */
|
|
int glConsoleSetCursorStyle(int style_num, gl_console_t * gl_console) {
|
|
|
|
if (gl_console == NULL)
|
|
return PROJECTM_FAILURE;
|
|
|
|
gl_console->cursor_style = style_num;
|
|
|
|
return PROJECTM_SUCCESS;
|
|
}
|
|
|