summaryrefslogtreecommitdiffstats
path: root/thk04/scroll_layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thk04/scroll_layer.cpp')
-rw-r--r--thk04/scroll_layer.cpp215
1 files changed, 215 insertions, 0 deletions
diff --git a/thk04/scroll_layer.cpp b/thk04/scroll_layer.cpp
new file mode 100644
index 0000000..4df5724
--- /dev/null
+++ b/thk04/scroll_layer.cpp
@@ -0,0 +1,215 @@
+/* FreeJ
+ * Text Scroller layer
+ * (c) Copyright 2004 Denis Roio aka jaromil <jaromil@dyne.org>
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This source code 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.
+ * Please refer to the GNU Public License for more details.
+ *
+ * You should have received a copy of the GNU Public License along with
+ * this source code; if not, write to:
+ * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * "$Id: gen_layer.cpp,v 1.2 2004/05/02 10:43:03 jaromil Exp $"
+ *
+ * This is a simple vertical text scroller using prebuffered rendering
+ *
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include <font_acorn_8x8.h>
+#include <scroll_layer.h>
+#include <context.h>
+#include <jutils.h>
+#include <config.h>
+
+ScrollLayer::ScrollLayer()
+ :Layer() {
+
+ line_space = 2;
+ step = 2;
+ first = last = NULL;
+ procbuf = NULL;
+ wmax = 512; // default bound, init makes it exact
+ border = 10;
+ setname("SCR");
+}
+
+ScrollLayer::~ScrollLayer() {
+ close();
+}
+
+bool ScrollLayer::init(Context *scr) {
+ _init(scr,scr->screen->w,scr->screen->h,32);
+
+ wmax = geo.w/(CHAR_WIDTH+kerning); // max strings in a line
+
+ procbuf = malloc(geo.size);
+
+ kerning = 1;
+ return true;
+}
+
+void ScrollLayer::close() {
+ struct txtline *l, *tmp;
+ l = first;
+
+ // cleanup all the line buffers
+ while(l) {
+ if(l->buf) free(l->buf);
+ tmp = l->next;
+ free(l);
+ l = tmp;
+ }
+
+ if(procbuf) free(procbuf);
+ procbuf = NULL;
+ first = NULL; last = NULL;
+}
+
+void ScrollLayer::render(struct txtline *l) {
+ int x,y,i,c,f;
+ uint32_t *dst;
+
+ // raster textline rendering
+
+ for (y=0; y<CHAR_HEIGHT; y++) {
+ dst = (uint32_t*)l->buf + y*geo.w + border;
+ for(x=0;x<l->len;x++) {
+ f = fontdata[l->txt[x] * CHAR_HEIGHT + y];
+ for (i = CHAR_WIDTH-1; i >= 0; i--) {
+ if (f & (CHAR_START << i))
+ *dst = 0xffffffff;
+ dst++;
+ }
+ dst += kerning;
+ }
+ }
+
+ l->rendered = true;
+}
+
+
+bool ScrollLayer::open(char *file) {
+
+ FILE *fd;
+ char str[4096]; // 4096 width resolution is bound here
+ fd = fopen(file,"r");
+ if(!fd) {
+ error("ScrollLayer::open : error opening %s : %s",
+ file, strerror(errno));
+ return false;
+ }
+ while(!feof(fd)) {
+ if(fgets(str,511,fd) <0) {
+ error("ScrollLayer::open : error reading %s : %s",
+ file, strerror(errno));
+ break;
+ }
+ append(str);
+ }
+ fclose(fd);
+ return true;
+}
+
+void ScrollLayer::append(char *txt) {
+ int c;
+ struct txtline *l;
+
+ // allocate structure and set all to 0
+ l = (struct txtline*)calloc( 1, sizeof( struct txtline ) );
+
+ // check length
+ l->len = strlen(txt);
+ if(!l->len) { // null string?! abort
+ free(l);
+ return;
+ }
+ l->len = (l->len>wmax) ? wmax : l->len;
+ // if(txt[l->len] != '\0') txt[l->len] = '\0';
+ // make a copy of the string
+ l->txt = strdup(txt);
+ // put it last
+ if(last) last->next = l;
+ if(!first) first = l;
+ last = l;
+ // put it bottom
+ l->y = 0;
+
+ // allocate 32bit render buffer:
+ // horizontal screen stripe of font's height
+ l->buf = calloc ( geo.pitch*2, CHAR_HEIGHT );
+
+}
+
+
+bool ScrollLayer::keypress(SDL_keysym *keysym) {
+ return false;
+}
+
+
+void *ScrollLayer::feed() {
+ int c;
+ struct txtline *l, *tmp;
+ uint32_t *dst, *src;
+
+ jmemset(procbuf,0,geo.size);
+
+ if(!first) {
+ // deactivates if there is nothing to write
+ active = false;
+ return procbuf;
+ }
+
+ l = first;
+
+ while(l) {
+ l->y+=step;
+
+ // check if it needs to be rendered
+ if( !l->rendered ) {
+ // yes, this is the last entry we process!
+ render(l);
+ break;
+ }
+
+ // check if it flowed out of screen
+ if( l->y >= geo.h ) {
+ // yes, delete the line!
+ tmp = l->next;
+
+
+ tmp->prev = l->prev;
+ if(first==l) first = tmp;
+ else l->prev->next = tmp;
+ if(last==l) last = tmp;
+
+ if(l->buf) free(l->buf);
+ if(l->txt) free(l->txt);
+ free(l);
+ l = tmp;
+ continue;
+ }
+
+ // make space in between
+ if(l->y< CHAR_HEIGHT+line_space) break;
+
+ // blit to the buffer
+ jmemcpy( ((uint32_t*)procbuf) + geo.w*(geo.h-l->y),
+ l->buf, geo.pitch*CHAR_HEIGHT );
+
+ // dst += geo.w*line_space; ???
+ l = l->next;
+ }
+
+ return procbuf;
+}
+