Commit 76c58062 authored by Steven Fuller's avatar Steven Fuller

Added a double buffering hack of GtkImage. Not all drawing currently works.

Tried to speed up 3D drawing.  Found out that the current setup is rather
slow.
parent 1df33246
......@@ -16,7 +16,7 @@ SOFTOBJS = RefSprite.o SoftDraw.o SoftDraw2.o
OGLOBJS = GLDraw.o
SOBJS = $(OBJS) $(SOFTOBJS) vi_svga.o
XOBJS = $(OBJS) $(SOFTOBJS) vi_xlib.o
GOBJS = $(OBJS) $(SOFTOBJS) vi_gtk.o
GOBJS = $(OBJS) $(SOFTOBJS) vi_gtk.o gtkimagedb.o
GLOBJS = $(OBJS) $(OGLOBJS) vi_glx.o
DOBJS = $(OBJS) $(SOFTOBJS) vi_sdl.o
......@@ -49,6 +49,9 @@ $(DOBJS): Sounds.h Sprites.h States.h Wolf.h burger.h wolfdef.h
vi_gtk.o: vi_gtk.c
$(CC) -c vi_gtk.c $(CFLAGS) `gtk-config --cflags`
gtkimagedb.o: gtkimagedb.c gtkimagedb.h
$(CC) -c gtkimagedb.c $(CFLAGS) `gtk-config --cflags`
swolf3d: $(SOBJS)
$(CC) -o swolf3d $(SOBJS) $(SLFLAGS)
......
......@@ -109,3 +109,6 @@ Some functions were moved to different files to account for functions which
did not exist on some platforms, different rendering systems, etc.
Changes from the orignal source:
...
GtkImageDB (gtkimagedb.c and gtkimagedb.h) is based on gtk+ 1.2.10's
GtkImage code.
......@@ -223,6 +223,7 @@ void IO_ClearViewBuffer(void)
} while (--Count);
}
#if 0
void ScaledDraw(Byte *gfx, Word scale, Byte *vid, LongWord TheFrac, Word TheInt, Word Width, LongWord Delta)
{
LongWord OldDelta;
......@@ -270,6 +271,60 @@ void IO_ScaleWallColumn(Word x, Word scale, Word tile, Word column)
TheFrac,TheInt,VideoWidth,y<<8);
}
}
#endif
void ScaledDrawOld(Byte *gfx, Word scale, Byte *vid, LongWord TheFrac, Word TheInt, Word Width, LongWord Delta)
{
LongWord OldDelta;
while (scale--) {
*vid = *gfx;
vid += Width;
OldDelta = Delta;
Delta += TheFrac;
gfx += TheInt;
if (OldDelta > Delta)
gfx += 1;
}
}
static void ScaledDraw(Byte *gfx, Word scale, Byte *vid, LongWord TheFrac, Word Width, LongWord Delta)
{
while (scale--) {
*vid = gfx[TheFrac >> 24];
vid += Width;
TheFrac += Delta;
}
}
static void IO_ScaleWallColumn(Word x, Word scale, Word tile, Word column)
{
LongWord TheFrac;
LongWord y;
Byte *ArtStart;
if (scale) {
scale *= 2;
TheFrac = 0x80000000UL / scale;
ArtStart = &ArtData[tile][column<<7];
if (scale < VIEWHEIGHT) {
y = (VIEWHEIGHT - scale) / 2;
ScaledDraw(ArtStart,scale,&VideoPointer[(y*VideoWidth)+x],
0, VideoWidth, TheFrac);
return;
}
y = (scale-VIEWHEIGHT)/2;
y *= TheFrac;
ScaledDraw(ArtStart,VIEWHEIGHT,&VideoPointer[x],
y,VideoWidth,TheFrac);
}
}
typedef struct {
ShortWord Topy;
......@@ -321,7 +376,7 @@ void IO_ScaleMaskedColumn(Word x,Word scale, unsigned short *CharPtr,Word column
}
RunCount = Y2-Y1;
if (RunCount)
ScaledDraw(&CharPtr2[Index],RunCount,
ScaledDrawOld(&CharPtr2[Index],RunCount,
&Screenad[Y1*VideoWidth],TFrac,TInt,VideoWidth, Delta);
}
}
......
......@@ -217,7 +217,15 @@ void IO_DrawStatusBar(void)
void IO_DisplayViewBuffer (void)
{
BlastScreen();
Rect r;
/* BlastScreen(); */
r.left = 0;
r.top = 0;
r.right = ScaleX(320);
r.bottom = ScaleY(160);
BlastScreen2(&r);
/* if this is the first frame rendered, upload everything and fade in */
if (firstframe) {
FadeTo(rGamePal);
......
......@@ -13,19 +13,26 @@ Psyched bar
pause key
About Box
Detect Shareware version, End Game box (Sharware/Retail)
remove PACKED
add better error checking for invalid file in res.c
select resolution to use
options dialog: resolution, speed (fps)
make sure all needed keys work
mouse support
options dialog: mouse enabled
sound (/dev/dsp?)
music (what format?, mp3 - there's smpeg?)
options dialog: sound enabled, music enabled
options file
input config
.wolf3d/{macfull,macshare} ?
command line options
verify other todo lists are also complete
make sure all desired options have been added
check bigendianesss
try to speed drawing up
play through testing
update copyrights where needed
Documentation
--------- release one anytime after this point ---------
SDL support (for full screen), optional
......
......@@ -357,25 +357,28 @@ Again:
void PlayLoop(void)
{
LongWord Timer;
LongWord Timer, Delay;
InitGameCounter();
InitRendCounter();
LastTicCount = ReadTick();
do {
Timer = ReadTick(); /* How much time has elapsed */
TicCount = (Timer-LastTicCount);
gamestate.playtime += TicCount; /* Add the physical time to the elapsed time */
if (!SlowDown)
Delay = 4; /* 15 Hz */
else
Delay = 2; /* 30 Hz */
LastTicCount=Timer;
do {
Timer = ReadTick();
} while ((Timer-LastTicCount) < Delay);
if (!SlowDown) {
TicCount = 4; /* Adjust from 4 */
}
if (TicCount>=5) {
TicCount = 4;
}
TicCount = (Timer-LastTicCount);
/*
printf("Timer: %d, Tic = %d\n", Timer, TicCount);
*/
gamestate.playtime += TicCount;
LastTicCount=Timer;
IO_CheckInput(); /* Read the controls from the system */
......
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
/* GdkImageDB: hacked up version of gtkimage.c/gtkimage.h from gtk+-1.2.10 */
#include <gtk/gtkcontainer.h>
#include <gdk/gdk.h>
#include "gtkimagedb.h"
static void gtk_imagedb_class_init (GtkImageDBClass *klass);
static void gtk_imagedb_init (GtkImageDB *image);
static gint gtk_imagedb_expose (GtkWidget *widget,
GdkEventExpose *event);
GtkType
gtk_imagedb_get_type (void)
{
static GtkType image_type = 0;
if (!image_type)
{
static const GtkTypeInfo image_info =
{
"GtkImageDB",
sizeof (GtkImageDB),
sizeof (GtkImageDBClass),
(GtkClassInitFunc) gtk_imagedb_class_init,
(GtkObjectInitFunc) gtk_imagedb_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
image_type = gtk_type_unique (GTK_TYPE_MISC, &image_info);
}
return image_type;
}
static void
gtk_imagedb_class_init (GtkImageDBClass *class)
{
GtkWidgetClass *widget_class;
widget_class = (GtkWidgetClass*) class;
widget_class->expose_event = gtk_imagedb_expose;
}
static void
gtk_imagedb_init (GtkImageDB *image)
{
GTK_WIDGET_SET_FLAGS (image, GTK_NO_WINDOW);
image->image[0] = NULL;
image->image[1] = NULL;
image->current = 1;
image->mask = NULL;
}
GtkWidget*
gtk_imagedb_new (GdkImage *val1, GdkImage *val2,
GdkBitmap *mask)
{
GtkImageDB *image;
g_return_val_if_fail (val1 != NULL, NULL);
g_return_val_if_fail (val2 != NULL, NULL);
g_return_val_if_fail (val1->width == val2->width, NULL);
g_return_val_if_fail (val1->height == val2->height, NULL);
g_return_val_if_fail (val1->depth == val2->depth, NULL);
g_return_val_if_fail (val1->bpl == val2->bpl, NULL);
image = gtk_type_new (GTK_TYPE_IMAGEDB);
gtk_imagedb_set (image, val1, val2, mask);
return GTK_WIDGET (image);
}
void
gtk_imagedb_set (GtkImageDB *image,
GdkImage *val1, GdkImage *val2,
GdkBitmap *mask)
{
g_return_if_fail (image != NULL);
g_return_if_fail (GTK_IS_IMAGEDB (image));
g_return_if_fail (val1 != NULL);
g_return_if_fail (val2 != NULL);
g_return_if_fail (val1->width == val2->width);
g_return_if_fail (val1->height == val2->height);
g_return_if_fail (val1->depth == val2->depth);
g_return_if_fail (val1->bpl == val2->bpl);
image->image[0] = val1;
image->image[1] = val2;
image->current = 1;
image->mask = mask;
GTK_WIDGET (image)->requisition.width = val1->width + GTK_MISC (image)->xpad * 2;
GTK_WIDGET (image)->requisition.height = val1->height + GTK_MISC (image)->ypad * 2;
if (GTK_WIDGET_VISIBLE (image))
gtk_widget_queue_resize (GTK_WIDGET (image));
}
void
gtk_imagedb_get (GtkImageDB *image,
GdkImage **val,
GdkBitmap **mask)
{
g_return_if_fail (image != NULL);
g_return_if_fail (GTK_IS_IMAGEDB (image));
if (val)
*val = image->image[image->current];
if (mask)
*mask = image->mask;
}
static gint
gtk_imagedb_expose (GtkWidget *widget,
GdkEventExpose *event)
{
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_IMAGEDB (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget))
{
GtkImageDB *image;
GtkMisc *misc;
GdkRectangle area, image_bound, intersection;
gint x, y;
image = GTK_IMAGEDB (widget);
misc = GTK_MISC (widget);
x = (widget->allocation.x * (1.0 - misc->xalign) +
(widget->allocation.x + widget->allocation.width
- (widget->requisition.width - misc->xpad * 2)) *
misc->xalign) + 0.5;
y = (widget->allocation.y * (1.0 - misc->yalign) +
(widget->allocation.y + widget->allocation.height
- (widget->requisition.height - misc->ypad * 2)) *
misc->yalign) + 0.5;
if (image->mask)
{
gdk_gc_set_clip_mask (widget->style->black_gc, image->mask);
gdk_gc_set_clip_origin (widget->style->black_gc, x, y);
}
image_bound.x = x;
image_bound.y = y;
image_bound.width = image->image[image->current]->width;
image_bound.height = image->image[image->current]->height;
area = event->area;
if(gdk_rectangle_intersect(&image_bound, &area, &intersection))
{
gdk_draw_image (widget->window,
widget->style->black_gc,
image->image[image->current],
image_bound.x - x, image_bound.y - y,
image_bound.x, image_bound.y,
image_bound.width, image_bound.height);
}
if (image->mask)
{
gdk_gc_set_clip_mask (widget->style->black_gc, NULL);
gdk_gc_set_clip_origin (widget->style->black_gc, 0, 0);
}
}
return FALSE;
}
void gtk_imagedb_draw (GtkImageDB *image, GdkRectangle *rect)
{
g_return_if_fail (image != NULL);
g_return_if_fail (GTK_IS_IMAGEDB (image));
if (GTK_WIDGET_VISIBLE (image) && GTK_WIDGET_MAPPED (image))
{
GtkWidget *widget = GTK_WIDGET(image);
gint x, y, width, height;
if (rect) {
x = rect->x;
y = rect->y;
width = rect->width;
height = rect->height;
} else {
x = 0;
y = 0;
width = image->image[image->current]->width;
height = image->image[image->current]->height;
}
gdk_draw_image (widget->window,
widget->style->black_gc,
image->image[image->current],
0, 0,
x, y,
width, height);
}
}
gint gtk_imagedb_swap(GtkImageDB *image)
{
gint ret;
g_return_val_if_fail (image != NULL, -1);
g_return_val_if_fail (GTK_IS_IMAGEDB (image), -1);
ret = image->current;
image->current ^= 1;
return ret;
}
/* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library 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.
*/
/*
* Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#ifndef __GTK_IMAGEDB_H__
#define __GTK_IMAGEDB_H__
#include <gdk/gdk.h>
#include <gtk/gtkmisc.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GTK_TYPE_IMAGEDB (gtk_imagedb_get_type ())
#define GTK_IMAGEDB(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_IMAGEDB, GtkImageDB))
#define GTK_IMAGEDB_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_IMAGEDB, GtkImageDBClass))
#define GTK_IS_IMAGEDB(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_IMAGEDB))
#define GTK_IS_IMAGEDB_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IMAGEDB))
typedef struct _GtkImageDB GtkImageDB;
typedef struct _GtkImageDBClass GtkImageDBClass;
struct _GtkImageDB
{
GtkMisc misc;
GdkImage *image[2];
gint current;
GdkBitmap *mask;
};
struct _GtkImageDBClass
{
GtkMiscClass parent_class;
};
GtkType gtk_imagedb_get_type (void);
GtkWidget* gtk_imagedb_new (GdkImage *val1, GdkImage *val2,
GdkBitmap *mask);
gint gtk_imagedb_swap(GtkImageDB *image);
void gtk_imagedb_draw(GtkImageDB *image, GdkRectangle *rect);
void gtk_imagedb_set (GtkImageDB *image,
GdkImage *val1, GdkImage *val2,
GdkBitmap *mask);
void gtk_imagedb_get (GtkImageDB *image,
GdkImage **val,
GdkBitmap **mask);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_IMAGEDB_H__ */
......@@ -100,7 +100,7 @@ static struct timeval t0;
LongWord ReadTick()
{
struct timeval t1;
long secs, usecs;
int secs, usecs;
if (t0.tv_sec == 0) {
gettimeofday(&t0, NULL);
......
......@@ -20,30 +20,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include "gtkimagedb.h"
#include "wolfdef.h"
Byte *gfxbuf;
GtkWidget *win;
GtkWidget *main_vbox;
GtkWidget *menubar;
GtkItemFactory *item_factory;
GtkAccelGroup *accel_group;
static GtkWidget *win;
static GtkWidget *main_vbox;
static GtkWidget *menubar;
static GtkItemFactory *item_factory;
static GtkAccelGroup *accel_group;
GtkWidget *event_box;
GdkVisual *visual;
GdkImage *image;
GtkImage *image_area;
static GtkWidget *event_box;
static GdkVisual *visual;
static GdkImage *image[2];
static GtkImageDB *image_area;
static gint current;
GdkColormap *cmap;
GdkColor game_colors[256], default_colors[256];
static GdkColormap *cmap;
static GdkColor game_colors[256], default_colors[256];
int image_focus = 1;
static int image_focus = 1;
void Quit();
......@@ -208,9 +211,10 @@ int main(int argc, char *argv[])
gtk_widget_show(menubar);
/* Create image and image area */
image = gdk_image_new(GDK_IMAGE_FASTEST, visual, 320, 200);
image_area = (GtkImage *)gtk_image_new(image, NULL);
/* Create (temp) image and image area */
image[0] = gdk_image_new(GDK_IMAGE_FASTEST, visual, 320, 200);
image[1] = gdk_image_new(GDK_IMAGE_FASTEST, visual, 320, 200);
image_area = (GtkImageDB *)gtk_imagedb_new(image[0], image[1], NULL);
gtk_signal_connect(GTK_OBJECT(image_area), "draw", GTK_SIGNAL_FUNC(draw), NULL);
gtk_signal_connect(GTK_OBJECT(image_area), "draw_default", GTK_SIGNAL_FUNC(draw_default), NULL);
......@@ -239,7 +243,7 @@ int main(int argc, char *argv[])
/* Game-related initialization */
InitData();
GameViewSize = 0;
GameViewSize = 3;
NewGameWindow(GameViewSize);
ClearTheScreen(BLACK);
......@@ -259,8 +263,10 @@ void Quit(char *str)
free(gfxbuf);
#endif
if (image)
gdk_image_destroy(image);
if (image[0])
gdk_image_destroy(image[0]);
if (image[1])
gdk_image_destroy(image[1]);
if (str && *str) {
fprintf(stderr, "%s\n", str);
......@@ -287,8 +293,27 @@ int VidWidth, VidHeight, ViewHeight;
#define h VidHeight
#define v ViewHeight
void BlastScreen()
{
#ifdef SLOWDRAW
memcpy(image->mem, gfxbuf, w * h);
gtk_widget_draw(GTK_WIDGET(image_area), NULL);
#else
return;
current = gtk_imagedb_swap(image_area);
gtk_imagedb_draw(image_area, NULL);
gfxbuf = image[current]->mem;
VideoPointer = gfxbuf;
#endif
}
void BlastScreen2(Rect *BlastRect)
{
#ifdef SLOWDRAW
GdkRectangle r;
r.x = BlastRect->left;
......@@ -296,8 +321,6 @@ void BlastScreen2(Rect *BlastRect)
r.width = BlastRect->right - BlastRect->left;
r.height = BlastRect->bottom - BlastRect->top;
#ifdef SLOWDRAW
#if 1
memcpy(image->mem, gfxbuf, w * h);
#else
......@@ -314,20 +337,23 @@ void BlastScreen2(Rect *BlastRect)
ptrd += image->bpl;
}
*/
#endif
#endif
gtk_widget_draw(GTK_WIDGET(image_area), &r);
}
#else
GdkRectangle r;
void BlastScreen()
{
#ifdef SLOWDRAW
memcpy(image->mem, gfxbuf, w * h);
#endif
r.x = BlastRect->left;
r.y = BlastRect->top;
r.width = BlastRect->right - BlastRect->left;
r.height = BlastRect->bottom - BlastRect->top;
gtk_widget_draw(GTK_WIDGET(image_area), NULL);
current = gtk_imagedb_swap(image_area);
gtk_imagedb_draw(image_area, &r);
gfxbuf = image[current]->mem;
VideoPointer = gfxbuf;
#endif
}
Word VidXs[] = {320,512,640,640}; /* Screen sizes to play with */
......@@ -358,12 +384,14 @@ Word NewGameWindow(Word NewVidSize)
exit(EXIT_FAILURE);
}
if (image) {
gdk_image_destroy(image);
}
if (image[0])
gdk_image_destroy(image[0]);
if (image[1])
gdk_image_destroy(image[1]);
image = gdk_image_new(GDK_IMAGE_FASTEST, visual, w, h);
gtk_image_set(image_area, image, NULL);
image[0] = gdk_image_new(GDK_IMAGE_FASTEST, visual, w, h);
image[1] = gdk_image_new(GDK_IMAGE_FASTEST, visual, w, h);
gtk_imagedb_set(image_area, image[0], image[1], NULL);
/* Main window will autoshrink */
gtk_widget_set_usize(GTK_WIDGET(image_area), w, h);
......@@ -373,11 +401,13 @@ Word NewGameWindow(Word NewVidSize)
free(gfxbuf);
gfxbuf = malloc(w * h);
#else
gfxbuf = image->mem;
#endif
current = 0;
gfxbuf = (Byte *)image[current]->mem;
#endif
VideoPointer = gfxbuf;
VideoWidth = w;
InitYTable();
SetAPalette(rBlackPal);
ClearTheScreen(BLACK);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment