2007-06-14
This commit is contained in:
parent
e20673c2cd
commit
1ae34ae340
52
ai.cpp
Normal file
52
ai.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <cassert>
|
||||
#include "ai.h"
|
||||
#include "opengta.h"
|
||||
#include "game_objects.h"
|
||||
#include "cell_iterator.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
namespace AI {
|
||||
namespace Pedestrian {
|
||||
void walk_pavement(OpenGTA::Pedestrian* ped) {
|
||||
assert(ped);
|
||||
Util::CellIterator ci(ped->pos);
|
||||
if (!ci.isValid())
|
||||
return;
|
||||
OpenGTA::Map::BlockInfo & bi = ci.getBlock();
|
||||
//INFO << " ped in bt: " << int(bi.blockType()) << std::endl;
|
||||
//INFO << ped->pos.x << " " << ped->pos.z << std::endl;
|
||||
std::pair<bool, Util::CellIterator> f = ci.findNeighbourWithType(3, ped->rot);
|
||||
if (f.first) {
|
||||
//INFO << "next: " << f.second.x << " " << f.second.y << std::endl;
|
||||
ped->aiData.pos1 = Vector3D(f.second.x+0.5f, ped->pos.y, f.second.y+0.5f);
|
||||
ped->aiMode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void moveto_shortrange(OpenGTA::Pedestrian *ped) {
|
||||
assert(ped);
|
||||
float d = Util::distance(ped->pos, ped->aiData.pos1);
|
||||
//INFO << "dist: " << d << std::endl;
|
||||
float a = Util::xz_turn_angle(ped->pos, ped->aiData.pos1);
|
||||
float da = Util::xz_angle(ped->pos, ped->aiData.pos1);
|
||||
//INFO << a << std::endl;
|
||||
//INFO << "rot " << ped->rot << std::endl;
|
||||
ped->m_control.setMoveForward(false);
|
||||
ped->m_control.setTurnLeft(false);
|
||||
ped->m_control.setTurnRight(false);
|
||||
//INFO << ped->rot + a << std::endl;
|
||||
if (fabs(ped->rot - da) > 5) {
|
||||
if (a > 0)
|
||||
ped->m_control.setTurnLeft(true);
|
||||
else
|
||||
ped->m_control.setTurnRight(true);
|
||||
}
|
||||
if (fabs(ped->rot - da) < 120 && d > 0.19f)
|
||||
ped->m_control.setMoveForward(true);
|
||||
if (d <= 0.19f)
|
||||
ped->aiMode = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
16
ai.h
Normal file
16
ai.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef OGTA_AI_H
|
||||
#define OGTA_AI_H
|
||||
|
||||
namespace OpenGTA {
|
||||
class Pedestrian;
|
||||
|
||||
namespace AI {
|
||||
namespace Pedestrian {
|
||||
void walk_pavement(OpenGTA::Pedestrian*);
|
||||
void moveto_shortrange(OpenGTA::Pedestrian*);
|
||||
void move_away(OpenGTA::Pedestrian*);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -39,9 +39,9 @@ namespace OpenGTA {
|
||||
Loki::DefaultLifetime, Loki::SingleThreaded> BlockDataHolder;
|
||||
}
|
||||
|
||||
#define SLOPE_RAW_DATA BlockDataHolder::Instance().slope_raw_data
|
||||
#define SLOPE_TEX_DATA BlockDataHolder::Instance().slope_tex_data
|
||||
#define LID_NORMAL_DATA BlockDataHolder::Instance().lid_normal_data
|
||||
#define SLOPE_RAW_DATA OpenGTA::BlockDataHolder::Instance().slope_raw_data
|
||||
#define SLOPE_TEX_DATA OpenGTA::BlockDataHolder::Instance().slope_tex_data
|
||||
#define LID_NORMAL_DATA OpenGTA::BlockDataHolder::Instance().lid_normal_data
|
||||
|
||||
|
||||
#endif
|
||||
|
61
bugs.rec
61
bugs.rec
@ -1,19 +1,72 @@
|
||||
Bug: style001.gry bridge texture artifacts
|
||||
Image: http://skybound.portland.co.uk/ogta/bugs_in_transparent_texture_2006-10-03.jpg
|
||||
Image: http://picasaweb.google.com/under.northern.sky/OpenGTAScreenshots/photo#5015284379944604402
|
||||
black pixel inside a side texture (nyc.cmp)... thus begins the
|
||||
'how many errors can there be about black vs. transparent contest'.
|
||||
%%
|
||||
Bug: wrong block texture coords
|
||||
Image: http://lh6.google.com/image/under.northern.sky/RZnek0op0yI/AAAAAAAAAB4/zfCFvPS8gWg/still_slope_tex_errors_2007-01-01.jpg
|
||||
Image: http://picasaweb.google.com/under.northern.sky/OpenGTAScreenshots/photo#5015284384239571746
|
||||
Status: maybe-closed
|
||||
Most likely the side that is a triangle and not a quad.
|
||||
Needs research if 'flipping' the texture is related.
|
||||
|
||||
Update: fixed for the case shown in the screenshot; may lurk on north/south sides of
|
||||
blocks, flipping/rotation influence remains unknown.
|
||||
%%
|
||||
Bug: transparent pixel in g24 tiles
|
||||
Image: http://lh4.google.com/image/under.northern.sky/Rh58SCRd8kI/AAAAAAAAAEQ/FK6KLriTfOs/nyc_gry_block_transparent_pixel_bug_2007-04-12.jpg
|
||||
Image: http://picasaweb.google.com/under.northern.sky/OpenGTAScreenshots/photo#5052612481245901378
|
||||
Those should probably just be black. It is not a very obvious
|
||||
error, but it should be fixed.
|
||||
%%
|
||||
Bug: black border around sprites
|
||||
Image: http://lh4.google.com/image/under.northern.sky/Rh58SCRd8lI/AAAAAAAAAEY/tnMwSk8IVok/g24_obj_black_border_2007-04-12.jpg
|
||||
Image: http://picasaweb.google.com/under.northern.sky/OpenGTAScreenshots/photo#5052612481245901394
|
||||
Simply doesn't look good, especially with g24 graphics.
|
||||
%%
|
||||
Bug: wrong-player position in viewer.exe when switching from free mode (F4)
|
||||
A position somewhat ~north~ is actually used; if you are at the north-border of the
|
||||
city this can cause the player to be spawned outside 0->255 ^2 range, which exits
|
||||
the program.
|
||||
%%
|
||||
Bug: wrong walk/run animations when armed
|
||||
Switching between forward/backward/run often changes the weapon as well; walking
|
||||
forward with the gun doesn't work at all.
|
||||
%%
|
||||
Bug: scale2x disabled in all previous releases
|
||||
The script prepare_build.sh defines -DDO_SCALEX while the code actually is
|
||||
activated by -DDO_SCALE2X; errare humanum est.
|
||||
|
||||
This bug will be closed when the next release includes this feature; otherwise
|
||||
see cvs.
|
||||
%%
|
||||
Bug: switching to/from fullscreen (at runtime) is broken on Windows (again?)
|
||||
Most polygons are plain white, some strange rendering errors appear as well;
|
||||
aka. oh gl-context, where did all my textures go?
|
||||
|
||||
Does this affect switching the screen resolution as well? Probably :-(
|
||||
%%
|
||||
Bug: vertical sync - SDL_GL_SWAP_CONTROL
|
||||
Does not work in the Win32 binaries, the SDL version I used is too old.
|
||||
|
||||
Stopped doing anything on at least my Linux system (after an update) as well.
|
||||
%%
|
||||
Bug: Data _or_ interpretation - block type
|
||||
Image: http://picasaweb.google.com/under.northern.sky/OpenGTAScreenshots/photo#5060057403938727394
|
||||
Several problems may stem from the 'flags stored in block above the one with the graphic' gta-
|
||||
legacy. The symptom is: you can fall through some floor blocks!
|
||||
|
||||
Probably several cases exist; either a bug in my code or some quirk of the map format.
|
||||
%%
|
||||
Bug: Collision with 'flat' blocks
|
||||
Partially transparent blocks (sign posts, fence, etc.) need special rules to handle
|
||||
blocking of peds/projectiles/car; implemented only for peds.
|
||||
|
||||
Furthermore only works on nyc.cmp, need to research the tile-ids for the other style
|
||||
files.
|
||||
FIXME: which blocks should _not_ block projectiles?
|
||||
%%
|
||||
Bug: Pedestrian movement physics
|
||||
|
||||
1) Moving up/down on a slope should influence speed
|
||||
|
||||
2) You can walk up a single vertical wall (can be seen when walking on roofs;
|
||||
probably also teleports to the upper road when under the bridges in nyc.cmp.
|
||||
%%
|
||||
|
@ -93,9 +93,17 @@ void Matrix3D::Translate(const Vector3D & v)
|
||||
}
|
||||
|
||||
void Matrix3D::RotZ(float angle) {
|
||||
const float TO_RAD = M_PI / 180.0f;
|
||||
const float c = cosf(angle * M_PI / 180.0f);
|
||||
const float s = sinf(angle * M_PI / 180.0f);
|
||||
/*
|
||||
m[0][0] = cosf(angle*TO_RAD);
|
||||
m[1][0] = sinf(angle*TO_RAD);
|
||||
m[0][1] = -sinf(angle*TO_RAD);
|
||||
m[1][1] = cosf(angle*TO_RAD);
|
||||
*/
|
||||
m[0][0] = c;
|
||||
m[2][2] = c;
|
||||
m[0][2] = s;
|
||||
m[2][0] = -s;
|
||||
|
||||
}
|
||||
|
@ -93,11 +93,14 @@ struct Matrix3
|
||||
};
|
||||
static const Matrix3 Identity;
|
||||
|
||||
Vector3D& baseRow(int i) { return *((Vector3D*)m[i]); }
|
||||
//Vector3D& baseRow(int i) { return *((Vector3D*)m[i]); }
|
||||
float operator() (int i, int j) const { return m[i][j]; }
|
||||
float& operator() (int i, int j) { return m[i][j]; }
|
||||
};
|
||||
|
||||
Matrix3D PitchMatrix3D(const float theta);
|
||||
Matrix3D YawMatrix3D(const float theta);
|
||||
Matrix3D RollMatrix3D(const float theta);
|
||||
struct Matrix3D
|
||||
{
|
||||
union {
|
||||
@ -127,9 +130,11 @@ struct Matrix3D
|
||||
return *this = *this * m;
|
||||
}
|
||||
|
||||
/*
|
||||
friend Matrix3D PitchMatrix3D(const float theta);
|
||||
friend Matrix3D YawMatrix3D(const float theta);
|
||||
friend Matrix3D RollMatrix3D(const float theta);
|
||||
*/
|
||||
void rotate(const Vector3D& v);
|
||||
|
||||
Matrix3D Inverse() const;
|
||||
|
134
cvs_changelog.txt
Normal file
134
cvs_changelog.txt
Normal file
@ -0,0 +1,134 @@
|
||||
2007-06-14 skyb
|
||||
|
||||
* fixes for win32 build
|
||||
|
||||
* updated bugs, documentation, build system
|
||||
* preparing to change key input handling
|
||||
|
||||
2007-05-30 skyb
|
||||
|
||||
* added WGL swap interval feature
|
||||
* spriteplayer: try anim feature; updated docs
|
||||
* luaviewer: read config file
|
||||
* experimental parts of in-game gui
|
||||
* playing around with basic ped ai
|
||||
* environment variable influences language file
|
||||
* updated docs; added author of code fragment to license
|
||||
|
||||
2007-05-17 skyb
|
||||
|
||||
* derived EntityController registers state change
|
||||
* rotation fixes
|
||||
* fixes concerning weapons + moving
|
||||
* car deltas: damage, doors, lights
|
||||
* more about "shooting" (hit, damage, explode cars);
|
||||
col-det tries to find angle for peds (still always the same anim)
|
||||
* fix: choose correct sprType for non-CAR types (bike, bus, train)
|
||||
* gui: drawing a string right-to-left
|
||||
* Map::BlockInfo partial setXXX() functionality
|
||||
* choose fxt language file (not hardcoded to english anymore)
|
||||
* 'viewer' screen-gamma in game
|
||||
* updated usage & version info
|
||||
* code cleanup
|
||||
|
||||
2007-04-30 skyb
|
||||
|
||||
* updated bugs list; fixed image links
|
||||
* vsync options: none, sdl, glx
|
||||
* uses anisotropic texture filtering if extension is supported
|
||||
* viewer config options for above (and mipmap & scale2x)
|
||||
* playing around with car-data
|
||||
* cars block ped movement
|
||||
|
||||
2007-04-25 skyb
|
||||
|
||||
A number of helpers:
|
||||
* project housekeeping
|
||||
* data dumper tool for cars
|
||||
* fxt <-> txt converter (txt -> fxt partially working)
|
||||
* build_svg_rect: visually verify Rectangle operations
|
||||
* raw_image: generate information about gui 2d art
|
||||
|
||||
* projectile-wall collisions should now work on all tiles; minus: z-info,
|
||||
non-blocking ids
|
||||
* test code for block-type; minimap nows exports several bmps, viewer
|
||||
shows colored lines
|
||||
|
||||
2007-04-23 skyb
|
||||
|
||||
* main feature: projectile hits walls; flat case not working correctly
|
||||
* (partially?) fixed the triangle-slope texture bug; top/bottom sides?
|
||||
* gui.h/cpp is included, moved code into image_loader for reuse
|
||||
|
||||
2007-04-16 skyb
|
||||
|
||||
fix: allowing 24 bit color depth
|
||||
|
||||
really unimportant fixes
|
||||
|
||||
contains the code release date; may not be accurate in cvs but will serve
|
||||
as a kind of version-number for actual releases.
|
||||
|
||||
removing dependency on unused code
|
||||
|
||||
* feature: animated block textures
|
||||
* switching from GL matrix to calculations for obj position
|
||||
* collision: projectile + pedestrian
|
||||
* unique id generator
|
||||
* other helpers (not really used so far)
|
||||
|
||||
2007-04-12 skyb
|
||||
|
||||
Fixes, cleanup and new helpers... little new features:
|
||||
* prototype sounds: play fx, play music
|
||||
* many peds on map, running randomly around player
|
||||
|
||||
2007-02-25 skyb
|
||||
|
||||
* screen: try to guess color depth from bpp
|
||||
(fixes hang on < 32 bit x11 displays)
|
||||
* missing code from last commit
|
||||
|
||||
fix: lookup now gets level number; should work for all gta1 maps
|
||||
|
||||
* build script should detect if SDL_GL_SWAP_CONTROL is defined (by SDL
|
||||
>= 1.2.10)
|
||||
* sdl_init & videomode: check for errors
|
||||
|
||||
* sector name from message db
|
||||
* initial projectile support
|
||||
* minor game_object updates
|
||||
|
||||
2007-02-17 skyb
|
||||
|
||||
* abstract_container: return (reference to copy of) added T
|
||||
* enable weapons selection/animation
|
||||
* more screen config options
|
||||
* gui-object cleanup
|
||||
* file_helper: load vfs into mem (for Lua)
|
||||
* spriteplayer: update to new version (compiles again) + camera hack
|
||||
(gravity doubles
|
||||
as y-scroll switch)
|
||||
* build-system: config.h instead of -D defines; related changes
|
||||
* coldet/opensteer in license.txt
|
||||
|
||||
2007-02-16 skyb
|
||||
|
||||
* each explosion plays once and gets removed
|
||||
* FIXME: at high framerates there is a visible delay when the textures
|
||||
aren't loaded
|
||||
|
||||
* rewrote spritemanager & game objects
|
||||
* some other fixes
|
||||
* assorted helpers; sometimes even with testcase, generally not used at
|
||||
this time
|
||||
|
||||
A first halfway working version; some older features are broken,
|
||||
it may even compile (right now).
|
||||
|
||||
2007-01-09 skyb
|
||||
|
||||
Importing src release 2006-12-10
|
||||
|
||||
Initial revision
|
||||
|
@ -116,6 +116,7 @@ namespace OpenGTA {
|
||||
template<> void MainMsgLookup::load(const std::string & file) {
|
||||
unload();
|
||||
try {
|
||||
INFO << "Trying to load: " << file << std::endl;
|
||||
m_data = new MessageDB(file);
|
||||
}
|
||||
catch (const Exception & e) {
|
||||
|
53
doc/compiling.txt
Normal file
53
doc/compiling.txt
Normal file
@ -0,0 +1,53 @@
|
||||
= What happens when you call 'make' =
|
||||
|
||||
The main makefile checks the env-variable 'HOST';
|
||||
which is assumed to be "LINUX" or "WIN32", the latter actually being
|
||||
used to indicate cross-compiling using a mingw-toolchain.
|
||||
|
||||
The main makefile checks if the 'Loki'-library is already there;
|
||||
if not 'wget's it and calls loki.make(.w32_cross) to build it.
|
||||
|
||||
It then looks for a file named src_list.make; if that does not exist
|
||||
it calls "prepare_build.sh $HOST" which generates both src_list.make
|
||||
and config.h.
|
||||
|
||||
The script will only work on Linux where it will use pkg-config to
|
||||
find the libraries; I hardcoded many Win32 values pointing to my
|
||||
toolchain and library pathes.
|
||||
|
||||
Make now includes src_list.make and builds the default targets;
|
||||
there are more programs that can be build with an explicit
|
||||
"make $program_name"; look at src_list.make.
|
||||
|
||||
If you need to setup compiler/library paths src_list.make is the
|
||||
place to do it. Then run make again.
|
||||
|
||||
|
||||
= Features in config.h =
|
||||
|
||||
DO_SCALE2X
|
||||
Enable scale2x algorithm; so far only used for sprites, on if enabled.
|
||||
|
||||
HAVE_SDL_VSYNC
|
||||
Does the SDL header define SDL_GL_SWAP_CONTROL? Must be #undef-ined if
|
||||
not, may be undefined anyway (turn feature off) and it really depends
|
||||
whether the driver supports it (at runtime).
|
||||
|
||||
In the future a number of WITH_* defines will be used to enable
|
||||
support for library-dependent features (Lua, SDL_sound + SDL_mixer,
|
||||
SDL_image). For the moment only the Lua related flag changes 'viewer',
|
||||
the other features are only used in testcases.
|
||||
|
||||
DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT
|
||||
The initial screen size (unless otherwise defined); defaults to 640x480
|
||||
if not defined.
|
||||
|
||||
DEFAULT_SCREEN_VSYNC
|
||||
Default setting for vsync;can be one of 0, 1, 2
|
||||
|
||||
On Linux you can colorify the log-output by defining LOG_USE_ANSI_COLORS.
|
||||
|
||||
= If you modify the code yourself =
|
||||
|
||||
Note: the dependency system is somewhat broken, sometimes changes in
|
||||
header files are ignored; either "make clean" or "touch config.h".
|
26
doc/ped_remaps.txt
Normal file
26
doc/ped_remaps.txt
Normal file
@ -0,0 +1,26 @@
|
||||
style001.g24
|
||||
231 - 293
|
||||
|
||||
style002.g24
|
||||
238 - 300
|
||||
|
||||
style003.g24
|
||||
219 - 281
|
||||
-------------
|
||||
1.g24
|
||||
75 - 131
|
||||
HK 93
|
||||
PRIESTS 94
|
||||
idx: 660
|
||||
|
||||
2.g24
|
||||
79 - 135
|
||||
HARE KRISHNAS 97
|
||||
DOCTOR/PRIESTS 98
|
||||
idx: 662
|
||||
|
||||
3.g24
|
||||
60 - 116
|
||||
HK 78
|
||||
PRIESTS 79
|
||||
idx: 675
|
173
doc/sprites.txt
Normal file
173
doc/sprites.txt
Normal file
@ -0,0 +1,173 @@
|
||||
style001.gry
|
||||
|
||||
604 - 611 : rotating "x"
|
||||
612 - 619 : rotating coin
|
||||
|
||||
620 - 627 : player, walking
|
||||
628 - 635 : player, running?
|
||||
658 - 661 : player, falling?
|
||||
678 - 689 : player, walking 2?
|
||||
738 - 745 : player, flame-thrower, standing
|
||||
746 - 753 : player, flame-thrower, walking
|
||||
754 - 755 : player, flame-thrower, standing?
|
||||
756 - 763 : player, gun, standing
|
||||
764 - 771 : player, gun, running?
|
||||
772 - 773 : player, gun, standing?
|
||||
774 - 781 : player, big-gun, standing
|
||||
782 - 789 : player, big-gun, running?
|
||||
790 - 791 : player, big-gun, standing?
|
||||
792 - 796 : player, electro-death
|
||||
|
||||
797 - 800 : player, swimming?
|
||||
801 - 808 : player, punching?
|
||||
|
||||
|
||||
style002.gry
|
||||
|
||||
99 - 105 : cone, tumbling
|
||||
106 - 111 : ring?
|
||||
112 - 124 : plant?
|
||||
125 - 129 : road barrier
|
||||
130 - 136 : road barrier, broken
|
||||
|
||||
622 - 629 : player, walking
|
||||
|
||||
811 - 818 : cop, walking
|
||||
819 - 826 : cop, moving?
|
||||
827 - 844 : cop, driving?
|
||||
845 - 848 : ???
|
||||
|
||||
style001.g24
|
||||
|
||||
117 - 127 : smoke, circle, small
|
||||
128 - 131 : grey bar | dissolving
|
||||
132 - 135 : red bar | dissolving
|
||||
136 - 140 : small water splash
|
||||
141 - 146 : blood dissolving
|
||||
147 - 150 : brown bar | dissolving
|
||||
151 - 166 : fire
|
||||
167 - 173 : big water dissolving
|
||||
|
||||
174 : tree
|
||||
175 - 176: green/grey blob?
|
||||
|
||||
188 : box, top open, cross
|
||||
189 : closed box; x?
|
||||
190 : box, top open, rockets?
|
||||
191 : telephone
|
||||
192 : telephone, arrow
|
||||
193 : telephone, arrow, highlight
|
||||
194 : white circle, pickup package
|
||||
|
||||
247 - 257 : smoke, right->left, dissolving
|
||||
258 - 265 : small flames
|
||||
266 - 273 : water, fire truck
|
||||
274 - 281 : water hits fire
|
||||
|
||||
282 : fire truck part?
|
||||
283 - 294 : grey smoke, cirle, growing, gets darker
|
||||
296 - 306 : smoke?, at bottom
|
||||
307 - 313 : train door open?
|
||||
315 - 326 : big water splash
|
||||
|
||||
327 - 330/331? : fire truck parts
|
||||
|
||||
332 - 342 : small smoke (again)
|
||||
342 - 352 : like above???
|
||||
354 - 365 : blood grow + dissolve?
|
||||
366 : big blood splash
|
||||
|
||||
367 - 377 : smoke, cone from bottom
|
||||
393 - 403 : flames, from bottom, flame-thrower?
|
||||
404 - 411 : rotating canister
|
||||
412 - 419 : rotating gun
|
||||
420 - 432 : crate; breaking after first frame
|
||||
434 - 441 : race finish flag
|
||||
442 - 454 : crate + stuff; breaking
|
||||
455 : green blob
|
||||
456 : red blob
|
||||
457 - 464 : helicopter blades
|
||||
465 - 472 : uzi, rotating
|
||||
473 - 480 : rocket-launcher rotating
|
||||
481 - 488 : flame-thrower rotating
|
||||
489 - 496 : red canister rotating
|
||||
497 - 504 : red ? rotating
|
||||
506 - 513 : info-sign-post rotating
|
||||
514 - 521 : blue shield?
|
||||
522 - 529 : car speed up
|
||||
530 - 537 : jail free
|
||||
538 - 545 : extra life
|
||||
546 - 553 : multiplier up
|
||||
554 - 561 : police bribe
|
||||
|
||||
|
||||
ped1
|
||||
|
||||
second col: (#frames - 1)
|
||||
|
||||
0|7|walk
|
||||
8|7|running forward
|
||||
16|0|sitting in car
|
||||
17|7|car exit
|
||||
25|7|car enter
|
||||
33|0|sitting in car
|
||||
34|3|unused junk
|
||||
38|2|frames, looped while falling
|
||||
41|0|frame, sliding UNDER car
|
||||
42|1|frames, usual death pose
|
||||
44|0|special death pose when shot in back
|
||||
45|1|played when you get shot in front
|
||||
47|1|swimming, you CAN swim, but just for 1 cube long
|
||||
49|0|unknown, most likely not used
|
||||
50|5|punching while standing animation
|
||||
56|11|unknown, repeating unused animations
|
||||
68|9|seems like player strafing? unused.
|
||||
80|3|jumping onto motorbike
|
||||
84|0|sitting on a motorbike
|
||||
85|3|exitting motorbike
|
||||
89|0|shooting handgun while standing still
|
||||
91|2|played when you jump onto car
|
||||
94|0|played while you slide on cars
|
||||
95|1|played when you drop off a car sliding
|
||||
97|0|repeated sitting in car
|
||||
98|0|STANDING COMPLETELY STILL
|
||||
99|7|walking shooting handgun
|
||||
107|7|running shooting handgun
|
||||
115|2|riding a skateboard? unused.
|
||||
118|7|walking shooting flamethrower
|
||||
126|7|running shooting flamethrower
|
||||
134|1|identical standing shooting flamethrower
|
||||
136|7|walking shooting UZI
|
||||
144|7|running shooting UZI
|
||||
152|1|identical standing shooting uzi
|
||||
154|7|walking shooting rocket launcher
|
||||
162|7|running shooting rocket launcher
|
||||
170|1|identical standing shooting rocket launcher
|
||||
172|4|electrocution by electrified rail
|
||||
177|3|crawling on floor - unused
|
||||
181|7|running & punching
|
||||
|
||||
police ped
|
||||
|
||||
189 - 196 : walking
|
||||
197 - 204 : running
|
||||
205 : sitting
|
||||
206 - 213 : exit car
|
||||
214 - 221 : enter car
|
||||
222 : sitting
|
||||
227 - 228 : falling
|
||||
229 : slide under
|
||||
230 : shot front?
|
||||
231 - 233 : dead? (3 identical frames; lying)
|
||||
234 : ???
|
||||
235 : same as 230?
|
||||
236 - 237 : drowning? different ped colour??
|
||||
238 : shot in back
|
||||
239 - 243 : arrest?
|
||||
269/270? - 272 : enter bike
|
||||
273 : sitting on bike
|
||||
274 - 277 : exit bike
|
||||
278 : standing, gun
|
||||
278 - 279 : shoot gun?
|
||||
288 - 292 : electro-death
|
||||
293 - 294 : shoot uzi
|
27
doc/using_mods.txt
Normal file
27
doc/using_mods.txt
Normal file
@ -0,0 +1,27 @@
|
||||
Mods can (in theory) be downloaded and used directly
|
||||
as the ZIP file.
|
||||
|
||||
The install procedure in readme.txt is slightly dated,
|
||||
'viewer' actually does the following:
|
||||
|
||||
* look for environment variable "OGTA_DATA"; if it exists
|
||||
this is used as the base-data source.
|
||||
By default this is the file 'gtadata.zip' searched in
|
||||
the current directory (at viewer runtime).
|
||||
|
||||
If this source is not valid the directory where viewer
|
||||
is installed is checked before giving up.
|
||||
|
||||
* look for environment variable "OGTA_MOD"; if it exists
|
||||
and is a valid data-source all files contained within
|
||||
will overlay files in the base data source.
|
||||
This is not used by default.
|
||||
|
||||
To load a mod I use something like this:
|
||||
OGTA_MOD=mods/a_mod.zip ./viewer [...] -m map_filename -g style_filename
|
||||
|
||||
In this case you have to use -m & -g and use the filenames
|
||||
contained in the zip (note upper/lower case).
|
||||
|
||||
Similiar to gtadata.zip the files have to be in the 'root' of
|
||||
the ZIP file, not in sub-directory.
|
@ -41,6 +41,13 @@ namespace OpenGTA {
|
||||
rawData = v;
|
||||
}
|
||||
|
||||
bool ControllerWithMemory::statusChanged() {
|
||||
bool res = (rawData != lastRawData);
|
||||
if (res)
|
||||
lastRawData = rawData;
|
||||
return res;
|
||||
}
|
||||
|
||||
void PedController::setTurnLeft(bool press) {
|
||||
dataSet.set_item(0, press);
|
||||
}
|
||||
|
@ -34,17 +34,31 @@ namespace OpenGTA {
|
||||
void zero();
|
||||
typedef uint32_t Storage_T;
|
||||
void setRaw(Storage_T v);
|
||||
inline const Storage_T & getRaw() { return rawData; }
|
||||
protected:
|
||||
EntityController(const EntityController & other);
|
||||
Storage_T rawData;
|
||||
Util::Set dataSet;
|
||||
};
|
||||
|
||||
class ControllerWithMemory : public EntityController {
|
||||
public:
|
||||
ControllerWithMemory() : EntityController(),
|
||||
lastRawData(rawData) {}
|
||||
ControllerWithMemory(const ControllerWithMemory & o) :
|
||||
EntityController(o), lastRawData(o.lastRawData) {}
|
||||
bool statusChanged();
|
||||
protected:
|
||||
Storage_T lastRawData;
|
||||
};
|
||||
|
||||
class Pedestrian;
|
||||
class PedController : public EntityController {
|
||||
// class PedController : public EntityController {
|
||||
class PedController : public ControllerWithMemory {
|
||||
public:
|
||||
PedController() {}
|
||||
PedController(const PedController & other) : EntityController(other) {}
|
||||
// PedController(const PedController & other) : EntityController(other) {}
|
||||
PedController(const PedController & other) : ControllerWithMemory(other) {}
|
||||
void setTurnLeft(bool press = true);
|
||||
inline void releaseTurnLeft() { setTurnLeft(false); }
|
||||
void setTurnRight(bool press = true);
|
||||
|
619
game_objects.cpp
619
game_objects.cpp
@ -1,31 +1,40 @@
|
||||
/************************************************************************
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#include "game_objects.h"
|
||||
#include "spritemanager.h"
|
||||
#include "dataholder.h"
|
||||
#include "cell_iterator.h"
|
||||
#include "timer.h"
|
||||
#include "Functor.h"
|
||||
#include "plane.h"
|
||||
#include "ai.h"
|
||||
#include "localplayer.h"
|
||||
|
||||
// ugly fix for win32
|
||||
#ifdef WIN32
|
||||
#undef ERROR
|
||||
#define ERROR Util::Log::error(__FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
#define INT2FLOAT_WRLD(c) (float(c >> 6) + float(c % 64) / 64.0f)
|
||||
#define INT2F_DIV64(v) (float(v) / 64.0f)
|
||||
@ -63,8 +72,10 @@ namespace OpenGTA {
|
||||
assert(block);
|
||||
if (block->blockType() > 0) {
|
||||
float bz = slope_height_offset(block->slopeType(), v.x - x, v.z - z);
|
||||
if (block->slopeType() == 0 && block->blockType() != 5)
|
||||
if (block->slopeType() == 0 && (block->blockType() != 5 &&
|
||||
block->blockType() != 6))
|
||||
bz -= 1.0f;
|
||||
//INFO << "hit " << int(block->blockType()) << " at " << int(y) << std::endl;
|
||||
return v.y - (y + bz);
|
||||
}
|
||||
y -= 1.0f;
|
||||
@ -75,8 +86,10 @@ namespace OpenGTA {
|
||||
assert(block);
|
||||
if (block->blockType() > 0) {
|
||||
float bz = slope_height_offset(block->slopeType(), v.x - x, v.z - z);
|
||||
if (block->slopeType() == 0 && block->blockType() != 5)
|
||||
if (block->slopeType() == 0 && (block->blockType() != 5
|
||||
&& block->blockType() != 6))
|
||||
bz -= 1.0f;
|
||||
//INFO << "hit " << int(block->blockType()) << " at " << int(y) << std::endl;
|
||||
return v.y - (y + bz);
|
||||
}
|
||||
y += 1.0f;
|
||||
@ -130,14 +143,18 @@ namespace OpenGTA {
|
||||
animId = newId;
|
||||
}
|
||||
|
||||
uint32_t Pedestrian::fistAmmo = 0;
|
||||
|
||||
Pedestrian::Pedestrian(Vector3D e, const Vector3D & p, uint32_t id, Sint16 remapId) :
|
||||
GameObject_common(p),
|
||||
Sprite(0, remapId, GraphicsBase::SpriteNumbers::PED),
|
||||
OBox(TranslateMatrix3D(p), e * 0.5f),
|
||||
m_control(),
|
||||
speedForces(0, 0, 0) {
|
||||
speedForces(0, 0, 0),
|
||||
inventory(), activeWeapon(0), activeAmmo(&fistAmmo),
|
||||
aiData() {
|
||||
m_M = TranslateMatrix3D(p);
|
||||
m_M.RotZ(rot);
|
||||
m_M.RotZ(-rot);
|
||||
pedId = id;
|
||||
animId = 0;
|
||||
isDead = 0;
|
||||
@ -150,13 +167,17 @@ namespace OpenGTA {
|
||||
|
||||
pedId(other.pedId),
|
||||
m_control(),
|
||||
speedForces(other.speedForces) {
|
||||
speedForces(other.speedForces),
|
||||
inventory(other.inventory),
|
||||
activeWeapon(other.activeWeapon),
|
||||
activeAmmo(&inventory.find(activeWeapon)->second),
|
||||
aiData(other.aiData) {
|
||||
lastUpdateAt = other.lastUpdateAt;
|
||||
inGroundContact = other.inGroundContact;
|
||||
animId = other.animId;
|
||||
isDead = other.isDead;
|
||||
m_M = TranslateMatrix3D(other.pos);
|
||||
m_M.RotZ(other.rot);
|
||||
m_M.RotZ(-other.rot);
|
||||
}
|
||||
|
||||
extern void ai_step_fake(Pedestrian*);
|
||||
@ -168,26 +189,36 @@ namespace OpenGTA {
|
||||
}
|
||||
if (pedId < 0xffffffff)
|
||||
ai_step_fake(this);
|
||||
uint8_t activeWeapon = m_control.getActiveWeapon();
|
||||
//AI::Pedestrian::walk_pavement(this);
|
||||
if (aiMode) {
|
||||
AI::Pedestrian::moveto_shortrange(this);
|
||||
}
|
||||
uint8_t chooseWeapon = m_control.getActiveWeapon();
|
||||
if (chooseWeapon != activeWeapon) {
|
||||
if (chooseWeapon == 0) {
|
||||
activeWeapon = 0;
|
||||
activeAmmo = &fistAmmo;
|
||||
}
|
||||
else {
|
||||
InventoryMap::iterator i = inventory.find(chooseWeapon);
|
||||
if (i != inventory.end()) {
|
||||
activeWeapon = chooseWeapon;
|
||||
activeAmmo = &i->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
activeWeapon = chooseWeapon;
|
||||
switch(m_control.getMove()) {
|
||||
case 1:
|
||||
//if (!(animId == 2u + activeWeapon*3))
|
||||
// switchToAnim(2 + activeWeapon*3);
|
||||
if (m_control.getRunning()) {
|
||||
if (!(animId == 3u + activeWeapon*3))
|
||||
switchToAnim(3 + activeWeapon*3);
|
||||
}
|
||||
else {
|
||||
if (!(animId == 2u + activeWeapon*2))
|
||||
switchToAnim(2 + activeWeapon*2);
|
||||
if (!(animId == 2u + activeWeapon*3))
|
||||
switchToAnim(2 + activeWeapon*3);
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case 2:
|
||||
if (!(animId == 3u + activeWeapon*3))
|
||||
switchToAnim(3 + activeWeapon*3);
|
||||
break;
|
||||
*/
|
||||
case 0:
|
||||
if (!(animId == 1u + activeWeapon*3))
|
||||
switchToAnim(1 + activeWeapon*3);
|
||||
@ -201,7 +232,7 @@ namespace OpenGTA {
|
||||
anim.update(ticks);
|
||||
Uint32 delta = ticks - lastUpdateAt;
|
||||
//INFO << "delta = " << delta << " t: " << ticks << " lt: " << lastUpdateAt << std::endl;
|
||||
Vector3D moveDelta(0, 0, 0);
|
||||
moveDelta = Vector3D(0, 0, 0);
|
||||
switch(m_control.getTurn()) {
|
||||
case -1:
|
||||
rot -= 0.2f * delta;
|
||||
@ -234,6 +265,8 @@ namespace OpenGTA {
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
if (pedId == 0xffffffff) {
|
||||
}
|
||||
tryMove(pos + moveDelta);
|
||||
if (!inGroundContact) {
|
||||
speedForces.y += 0.0005f *delta;
|
||||
@ -258,6 +291,12 @@ namespace OpenGTA {
|
||||
SpriteManagerHolder::Instance().createProjectile(0, rot, pos, d1, ticks, pedId);
|
||||
lastWeaponTick = ticks;
|
||||
}
|
||||
/*
|
||||
if (m_control.statusChanged()) {
|
||||
INFO << "Ped-event id: " << pedId << " control: " << m_control.getRaw() <<
|
||||
" time: " << ticks << std::endl;
|
||||
}*/
|
||||
|
||||
//INFO << pos.x << " " << pos.y << " " << pos.z << std::endl;
|
||||
lastUpdateAt = ticks;
|
||||
}
|
||||
@ -271,12 +310,13 @@ namespace OpenGTA {
|
||||
OpenGTA::GraphicsBase & graphics = OpenGTA::StyleHolder::Instance().get();
|
||||
//INFO << heightOverTerrain(nPos) << std::endl;
|
||||
float hot = heightOverTerrain(nPos);
|
||||
if (hot > 0.1f)
|
||||
if (hot > 0.3f)
|
||||
inGroundContact = 0;
|
||||
else if (hot < 0.0) {
|
||||
INFO << "gone below: " << hot << " at " << nPos.x << ", " << nPos.y << ", " << nPos.z << std::endl;
|
||||
WARN << "gone below: " << hot << " at " << nPos.x << ", " << nPos.y << ", " << nPos.z << std::endl;
|
||||
nPos.y -= (hot - 0.3f);
|
||||
INFO << nPos.y << std::endl;
|
||||
//nPos.y += 1;
|
||||
//INFO << nPos.y << std::endl;
|
||||
inGroundContact = 1;
|
||||
}
|
||||
else {
|
||||
@ -287,34 +327,10 @@ namespace OpenGTA {
|
||||
nPos.y -= hot - 0.1f;
|
||||
}
|
||||
if (y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z)) && y > 0.0f) {
|
||||
//INFO << x << ", " << y << ", " << z << ": " << int(map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z))) << std::endl;
|
||||
OpenGTA::Map::BlockInfo * block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
||||
assert(block);/*
|
||||
if (block->blockType() > 0) {
|
||||
float bz = slope_height_offset(block->slopeType(), nPos.x - x, nPos.z - z);
|
||||
if (block->slopeType() == 0)
|
||||
bz -= 1.0f;
|
||||
if (inGroundContact) {
|
||||
nPos.y = y + bz + 0.3f;
|
||||
//pos = nPos;
|
||||
}
|
||||
else if (nPos.y - y - bz < 0.3f) {
|
||||
INFO << "ped near ground (type: " << int(block->blockType()) << " float-pos: "
|
||||
<< nPos.x << ", " << nPos.y << ", " << nPos.z << std::endl;
|
||||
inGroundContact = 1;
|
||||
nPos.y = y + bz + 0.3f;
|
||||
INFO << "height rewritten to: " << nPos.y << std::endl;
|
||||
//pos = nPos;
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
inGroundContact = 0;
|
||||
INFO << "lost footing: " << x << ", " << y << ", " << z << std::endl;
|
||||
}*/
|
||||
if (block->left && graphics.isBlockingSide(block->left)) { // && block->isFlat() == false) {
|
||||
assert(block);
|
||||
if (block->left && graphics.isBlockingSide(block->left)) {
|
||||
if (block->isFlat()) {
|
||||
//INFO << "xblock left: " << x - pos.x << std::endl;
|
||||
if (x - pos.x < 0 && x - pos.x > -0.2f) {
|
||||
nPos.x = (nPos.x < pos.x) ? pos.x : nPos.x;
|
||||
}
|
||||
@ -341,7 +357,7 @@ namespace OpenGTA {
|
||||
else if (pos.x - x - 1 < 0 && pos.x - x - 1 > -0.2f)
|
||||
nPos.x = (nPos.x > pos.x) ? pos.x : nPos.x;
|
||||
}
|
||||
if (block->top && graphics.isBlockingSide(block->top)) { // && block->isFlat() == false) {
|
||||
if (block->top && graphics.isBlockingSide(block->top)) {
|
||||
if (block->isFlat()) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "zblock top: " << z - pos.z << " tex: " << int(block->top) << std::endl;
|
||||
@ -384,7 +400,7 @@ namespace OpenGTA {
|
||||
}
|
||||
if (x < 255 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x+1), PHYSFS_uint8(z))) {
|
||||
block = map.getBlockAtNew(PHYSFS_uint8(x+1), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
||||
if (block->left && graphics.isBlockingSide(block->left)) { // && block->isFlat() == false) {
|
||||
if (block->left && graphics.isBlockingSide(block->left)) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "xblock left: " << x + 1 - pos.x << " tex: " << int(block->left)<< std::endl;
|
||||
#endif
|
||||
@ -411,7 +427,7 @@ namespace OpenGTA {
|
||||
}
|
||||
if (z < 255 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z+1))) {
|
||||
block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z+1), PHYSFS_uint8(y));
|
||||
if (block->top && graphics.isBlockingSide(block->top)) { // && block->isFlat() == false) {
|
||||
if (block->top && graphics.isBlockingSide(block->top)) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "zblock top: " << z + 1 - pos.z<< " tex: " << int(block->top) << std::endl;
|
||||
#endif
|
||||
@ -428,7 +444,15 @@ namespace OpenGTA {
|
||||
//if (inGroundContact)
|
||||
// pos = nPos;
|
||||
}
|
||||
if (inGroundContact)
|
||||
bool obj_blocked = false;
|
||||
std::list<Car> & list = SpriteManagerHolder::Instance().getList<Car>();
|
||||
for (std::list<Car>::iterator i = list.begin(); i != list.end(); i++) {
|
||||
if (isBoxInBox(*i)) {
|
||||
if (Util::distance(pos, i->pos) > Util::distance(nPos, i->pos))
|
||||
obj_blocked = true;
|
||||
}
|
||||
}
|
||||
if ((inGroundContact) && (obj_blocked == false))
|
||||
pos = nPos;
|
||||
//else
|
||||
// inGroundContact = 0;
|
||||
@ -438,9 +462,17 @@ namespace OpenGTA {
|
||||
void Pedestrian::die() {
|
||||
INFO << "DIE!!!" << std::endl;
|
||||
switchToAnim(42);
|
||||
if (isDead == 3) {
|
||||
anim.set(Util::Animation::STOPPED, Util::Animation::STOP);
|
||||
return;
|
||||
}
|
||||
anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::FCALLBACK);
|
||||
Loki::Functor<void> cmd(this, &Pedestrian::die);
|
||||
anim.setCallback(cmd);
|
||||
isDead++;
|
||||
}
|
||||
|
||||
void Pedestrian::getShot(bool front) {
|
||||
void Pedestrian::getShot(uint32_t shooterId, uint32_t dmg, bool front) {
|
||||
isDead = 1;
|
||||
switchToAnim(45);
|
||||
anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::FCALLBACK);
|
||||
@ -448,33 +480,278 @@ namespace OpenGTA {
|
||||
anim.setCallback(cmd);
|
||||
}
|
||||
|
||||
Car::Car(OpenGTA::Map::ObjectPosition& op, uint32_t id) :
|
||||
GameObject_common(Vector3D(INT2FLOAT_WRLD(op.x), 6.05f-INT2FLOAT_WRLD(op.z), INT2FLOAT_WRLD(op.y))),
|
||||
Sprite(0, -1, GraphicsBase::SpriteNumbers::CAR), OBox(),
|
||||
carInfo(*StyleHolder::Instance().get().findCarByModel(op.type)){
|
||||
CarSprite::CarSprite() : sprNum(0), remap(-1),
|
||||
sprType(GraphicsBase::SpriteNumbers::CAR), delta(0),
|
||||
deltaSet(sizeof(delta) * 8, (unsigned char*)&delta),
|
||||
animState() {}
|
||||
|
||||
CarSprite::CarSprite(const CarSprite & o) :
|
||||
sprNum(o.sprNum), remap(o.remap), sprType(o.sprType), delta(o.delta),
|
||||
deltaSet(sizeof(delta) * 8, (unsigned char*)&delta),
|
||||
animState(o.animState) {}
|
||||
|
||||
CarSprite::CarSprite(Uint16 sprN, Sint16 rem,
|
||||
GraphicsBase::SpriteNumbers::SpriteTypes sprT) : sprNum(sprN),
|
||||
remap(rem), sprType(sprT), delta(0),
|
||||
deltaSet(sizeof(delta) * 8, (unsigned char*)&delta),
|
||||
animState() {}
|
||||
|
||||
void CarSprite::setDamage(uint8_t k) {
|
||||
deltaSet.set_item(k, true);
|
||||
}
|
||||
|
||||
bool CarSprite::assertDeltaById(uint8_t k) {
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
PHYSFS_uint16 absNum = style.spriteNumbers.reIndex(sprNum, sprType);
|
||||
GraphicsBase::SpriteInfo * info = style.getSprite(absNum);
|
||||
if (k >= info->deltaCount)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CarSprite::openDoor(uint8_t k) {
|
||||
DoorDeltaAnimation dda(k, true);
|
||||
doorAnims.push_back(dda);
|
||||
}
|
||||
|
||||
void CarSprite::closeDoor(uint8_t k) {
|
||||
doorAnims.push_back(DoorDeltaAnimation(k, false));
|
||||
}
|
||||
|
||||
void CarSprite::setSirenAnim(bool on) {
|
||||
if (!(assertDeltaById(15) && assertDeltaById(16))) {
|
||||
ERROR << "Trying to set siren anim on car-sprite that has no such delta!" << std::endl;
|
||||
return;
|
||||
}
|
||||
animState.set_item(10, on);
|
||||
}
|
||||
|
||||
void CarSprite::update(Uint32 ticks) {
|
||||
|
||||
// siren anim indices
|
||||
#define DSI_1 15
|
||||
#define DSI_2 16
|
||||
|
||||
#define D_A_THEN_B(d, a, b) (d.get_item(a)) { d.set_item(a, false); d.set_item(b, true); }
|
||||
|
||||
// drive-anim
|
||||
if (animState.get_item(0)) {}
|
||||
/*
|
||||
if (ticks - lt_door > 500) {
|
||||
// 1-4 door-opening
|
||||
if (animState.get_item(1)) {
|
||||
deltaSet.set_item(6, true);
|
||||
}
|
||||
// 5-8 door-closing
|
||||
lt_door = ticks;
|
||||
}*/
|
||||
DoorAnimList::iterator i = doorAnims.begin();
|
||||
while (i != doorAnims.end()) {
|
||||
i->update(ticks);
|
||||
if (i->opening) {
|
||||
if (i->doorId == 0) {
|
||||
for (int k=6; k < 10; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 6, true);
|
||||
}
|
||||
else if (i->doorId == 1) {
|
||||
for (int k=11; k < 15; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 11, true);
|
||||
}
|
||||
else if (i->doorId == 2) {
|
||||
for (int k=20; k < 24; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 20, true);
|
||||
}
|
||||
else if (i->doorId == 3) {
|
||||
for (int k=24; k < 28; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 24, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i->doorId == 0) {
|
||||
for (int k=6; k < 10; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
if (i->getCurrentFrameNumber() > 0)
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 5, true);
|
||||
}
|
||||
else if (i->doorId == 1) {
|
||||
for (int k=11; k < 15; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
if (i->getCurrentFrameNumber() > 0)
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 10, true);
|
||||
}
|
||||
else if (i->doorId == 2) {
|
||||
for (int k=20; k < 24; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
if (i->getCurrentFrameNumber() > 0)
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 19, true);
|
||||
}
|
||||
else if (i->doorId == 3) {
|
||||
for (int k=24; k < 28; k++)
|
||||
deltaSet.set_item(k, false);
|
||||
if (i->getCurrentFrameNumber() > 0)
|
||||
deltaSet.set_item(i->getCurrentFrameNumber() + 23, true);
|
||||
}
|
||||
}
|
||||
if (i->get() == Util::Animation::STOPPED) {
|
||||
DoorAnimList::iterator j = i;
|
||||
i++;
|
||||
animState.set_item(j->doorId + 1, j->opening);
|
||||
doorAnims.erase(j);
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
if (animState.get_item(10)) {
|
||||
if (ticks - lt_siren > 500) {
|
||||
if D_A_THEN_B(deltaSet, DSI_1, DSI_2)
|
||||
else if D_A_THEN_B(deltaSet, DSI_2, DSI_1)
|
||||
else { deltaSet.set_item(DSI_1, true); deltaSet.set_item(DSI_2, false); }
|
||||
lt_siren = ticks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CarSprite::DoorDeltaAnimation::DoorDeltaAnimation(uint8_t dId, bool dOpen) :
|
||||
Util::Animation(4 + (dOpen ? 0 : 1), 5), doorId(dId), opening(dOpen) {
|
||||
if (!opening) {
|
||||
set(Util::Animation::PLAY_BACKWARD, Util::Animation::STOP);
|
||||
jumpToFrame(4, Util::Animation::PLAY_BACKWARD);
|
||||
}
|
||||
else {
|
||||
set(Util::Animation::PLAY_FORWARD, Util::Animation::STOP);
|
||||
}
|
||||
}
|
||||
|
||||
Car::Car(Vector3D & _pos, float _rot, uint32_t id, uint8_t _type, int16_t _remap) :
|
||||
GameObject_common(_pos, _rot),
|
||||
CarSprite(0, -1, GraphicsBase::SpriteNumbers::CAR), OBox(),
|
||||
carInfo(*StyleHolder::Instance().get().findCarByModel(_type)) {
|
||||
type = _type;
|
||||
carId = id;
|
||||
type = op.type;
|
||||
sprNum = carInfo.sprNum;
|
||||
if ((_remap > -1) && (StyleHolder::Instance().get().getFormat() == 0))
|
||||
remap = carInfo.remap8[_remap];
|
||||
fixSpriteType();
|
||||
m_Extent = Vector3D(INT2F_DIV128(carInfo.width),
|
||||
INT2F_DIV128(carInfo.depth),
|
||||
INT2F_DIV128(carInfo.height));
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
m_M.RotZ(-rot);
|
||||
hitPoints = carInfo.damagable;
|
||||
}
|
||||
|
||||
void Car::fixSpriteType() {
|
||||
if (carInfo.vtype == 3)
|
||||
sprType = GraphicsBase::SpriteNumbers::BIKE;
|
||||
else if (carInfo.vtype == 0)
|
||||
sprType = GraphicsBase::SpriteNumbers::BUS;
|
||||
else if (carInfo.vtype == 8)
|
||||
sprType = GraphicsBase::SpriteNumbers::TRAIN;
|
||||
}
|
||||
|
||||
Car::Car(OpenGTA::Map::ObjectPosition& op, uint32_t id) :
|
||||
GameObject_common(Vector3D(INT2FLOAT_WRLD(op.x), 6.05f-INT2FLOAT_WRLD(op.z), INT2FLOAT_WRLD(op.y))),
|
||||
CarSprite(0, -1, GraphicsBase::SpriteNumbers::CAR), OBox(),
|
||||
carInfo(*StyleHolder::Instance().get().findCarByModel(op.type)){
|
||||
carId = id;
|
||||
type = op.type;
|
||||
if (op.remap - 128 > 0) {
|
||||
if (StyleHolder::Instance().get().getFormat() == 0)
|
||||
remap = carInfo.remap8[op.remap-129];
|
||||
else
|
||||
WARN << "remap " << int(op.remap-129) <<
|
||||
" requested but not implemented for G24" << std::endl;
|
||||
}
|
||||
sprNum = carInfo.sprNum;
|
||||
fixSpriteType();
|
||||
m_Extent = Vector3D(INT2F_DIV128(carInfo.width),
|
||||
INT2F_DIV128(carInfo.depth) ,
|
||||
INT2F_DIV128(carInfo.height));
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
|
||||
rot = op.rotation * 360 / 1024;
|
||||
m_M.RotZ(-rot);
|
||||
hitPoints = carInfo.damagable;
|
||||
}
|
||||
|
||||
Car::Car(const Car & other) :
|
||||
GameObject_common(other), Sprite(other), OBox(other),
|
||||
GameObject_common(other), CarSprite(other), OBox(other),
|
||||
carInfo(*StyleHolder::Instance().get().findCarByModel(other.type)) {
|
||||
type = other.type;
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
m_M.RotZ(-rot);
|
||||
hitPoints = other.hitPoints;
|
||||
|
||||
carId = other.carId;
|
||||
}
|
||||
|
||||
void Car::update(Uint32 ticks) {
|
||||
//m_M = TranslateMatrix3D(pos);
|
||||
//m_M.RotZ(rot+90);
|
||||
CarSprite::update(ticks);
|
||||
}
|
||||
|
||||
void Car::damageAt(const Vector3D & hit, uint32_t dmg) {
|
||||
float angle = Util::xz_angle(Vector3D(0, 0, 0), hit);
|
||||
INFO << "hit angle: " << angle << std::endl;
|
||||
|
||||
/*
|
||||
* front rear
|
||||
* 270
|
||||
* 0 _|o---o| _ 180
|
||||
* |o---o|
|
||||
* 45 90
|
||||
*/
|
||||
#define A1 60
|
||||
#define A2 (180 - A1)
|
||||
#define A3 (180 + A1)
|
||||
#define A4 (360 - A1)
|
||||
|
||||
uint8_t k = 0;
|
||||
if (angle <= A1) {
|
||||
// front left
|
||||
k = 3;
|
||||
}
|
||||
else if (angle <= A2) {
|
||||
// left side
|
||||
k = 2;
|
||||
}
|
||||
else if (angle < 180.0f) {
|
||||
// rear left
|
||||
k = 1;
|
||||
}
|
||||
else if (angle <= A3) {
|
||||
// rear right
|
||||
k = 4;
|
||||
}
|
||||
else if (angle <= A4) {
|
||||
// right side
|
||||
k = 5;
|
||||
}
|
||||
else {
|
||||
// right front
|
||||
k = 0;
|
||||
}
|
||||
setDamage(k);
|
||||
hitPoints -= dmg;
|
||||
if (hitPoints <= 0)
|
||||
explode();
|
||||
}
|
||||
|
||||
void Car::explode() {
|
||||
//SpriteManagerHolder::Instance().removeCar(carId);
|
||||
//return;
|
||||
Vector3D exp_pos(pos);
|
||||
exp_pos.y += 0.1f;
|
||||
SpriteManagerHolder::Instance().createExplosion(exp_pos);
|
||||
sprNum = 0;
|
||||
remap = -1;
|
||||
sprType = GraphicsBase::SpriteNumbers::WCAR;
|
||||
delta = 0;
|
||||
}
|
||||
|
||||
SpriteObject::SpriteObject(OpenGTA::Map::ObjectPosition& op, uint32_t id) :
|
||||
@ -487,7 +764,7 @@ namespace OpenGTA {
|
||||
INT2F_DIV128(style.objectInfos[op.type]->depth),
|
||||
INT2F_DIV128(style.objectInfos[op.type]->height));
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
m_M.RotZ(-rot);
|
||||
rot = op.rotation * 360 / 1024;
|
||||
isActive = true;
|
||||
}
|
||||
@ -496,7 +773,7 @@ namespace OpenGTA {
|
||||
GameObject_common(pos), Sprite(sprNum, -1, sprT), OBox() {
|
||||
isActive = true;
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
m_M.RotZ(-rot);
|
||||
}
|
||||
|
||||
SpriteObject::SpriteObject(const SpriteObject & other) :
|
||||
@ -504,7 +781,7 @@ namespace OpenGTA {
|
||||
|
||||
objId(other.objId) {
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
m_M.RotZ(-rot);
|
||||
|
||||
isActive = other.isActive;
|
||||
}
|
||||
@ -525,6 +802,86 @@ namespace OpenGTA {
|
||||
typeId(other.typeId), delta(other.delta), endsAtTick(other.endsAtTick),
|
||||
owner(other.owner), lastUpdateAt(other.lastUpdateAt) {}
|
||||
|
||||
bool Projectile::testCollideBlock_flat(Util::CellIterator & ci, Vector3D & newp) {
|
||||
Map::BlockInfo & bi = ci.getBlock();
|
||||
if (bi.top) {
|
||||
Math::Plane plane(Vector3D(ci.x, ci.z, ci.y), Vector3D(0, 0, -1));
|
||||
Vector3D hit_pos;
|
||||
if (plane.segmentIntersect(pos, newp, hit_pos)) {
|
||||
INFO << "intersect flat-t: " << hit_pos.x << " " << hit_pos.y << " " <<hit_pos.z << std::endl;
|
||||
if (hit_pos.x >= ci.x && hit_pos.x <= ci.x + 1) {
|
||||
newp = hit_pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bi.left) {
|
||||
Math::Plane plane(Vector3D(ci.x, ci.z, ci.y), Vector3D(-1, 0, 0));
|
||||
Vector3D hit_pos;
|
||||
if (plane.segmentIntersect(pos, newp, hit_pos)) {
|
||||
INFO << "intersect flat-l: " << hit_pos.x << " " << hit_pos.y << " " <<hit_pos.z << std::endl;
|
||||
if (hit_pos.z >= ci.y && hit_pos.z <= ci.y + 1) {
|
||||
newp = hit_pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Projectile::testCollideBlock(Util::CellIterator & ci, Vector3D & newp) {
|
||||
Map::BlockInfo & bi = ci.getBlock();
|
||||
//INFO << "pos: " << ci.x << " " << ci.y << " " << ci.z << std::endl;
|
||||
//if (bi.isFlat())
|
||||
// return false;
|
||||
if (bi.left) {
|
||||
Math::Plane plane(Vector3D(ci.x, ci.z, ci.y), Vector3D(-1, 0, 0));
|
||||
Vector3D hit_pos;
|
||||
if (plane.segmentIntersect(pos, newp, hit_pos)) {
|
||||
INFO << "intersect left: " << hit_pos.x << " " << hit_pos.y << " " <<hit_pos.z << std::endl;
|
||||
if (hit_pos.z >= ci.y && hit_pos.z <= ci.y + 1) {
|
||||
newp = hit_pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bi.right && !bi.isFlat()) {
|
||||
Math::Plane plane(Vector3D(ci.x+1, ci.z, ci.y), Vector3D(1, 0, 0));
|
||||
Vector3D hit_pos;
|
||||
if (plane.segmentIntersect(pos, newp, hit_pos)) {
|
||||
INFO << "intersect right: " << hit_pos.x << " " << hit_pos.y << " " <<hit_pos.z << std::endl;
|
||||
if (hit_pos.z >= ci.y && hit_pos.z <= ci.y + 1) {
|
||||
newp = hit_pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bi.top) {
|
||||
Math::Plane plane(Vector3D(ci.x, ci.z, ci.y), Vector3D(0, 0, -1));
|
||||
Vector3D hit_pos;
|
||||
if (plane.segmentIntersect(pos, newp, hit_pos)) {
|
||||
INFO << "intersect top: " << hit_pos.x << " " << hit_pos.y << " " <<hit_pos.z << std::endl;
|
||||
if (hit_pos.x >= ci.x && hit_pos.x <= ci.x + 1) {
|
||||
newp = hit_pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bi.bottom && !bi.isFlat()) {
|
||||
Math::Plane plane(Vector3D(ci.x, ci.z, ci.y+1), Vector3D(0, 0, 1));
|
||||
Vector3D hit_pos;
|
||||
if (plane.segmentIntersect(pos, newp, hit_pos)) {
|
||||
INFO << "intersect bottom: " << hit_pos.x << " " << hit_pos.y << " " <<hit_pos.z << std::endl;
|
||||
if (hit_pos.x >= ci.x && hit_pos.x <= ci.x + 1) {
|
||||
newp = hit_pos;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Projectile::update(uint32_t ticks) {
|
||||
Uint32 dt = ticks - lastUpdateAt;
|
||||
Vector3D new_pos(pos + delta * dt);
|
||||
@ -538,49 +895,77 @@ namespace OpenGTA {
|
||||
continue;
|
||||
if (ped.isDead)
|
||||
continue;
|
||||
/*INFO << "ped " << ped.id() << " pos: " << ped.pos.x << " " << ped.pos.y << " " << ped.pos.z << std::endl;
|
||||
Vector3D p = ped.GetCenterPoint();
|
||||
INFO << "CP " << p.x << " " << p.y << " " << p.z << std::endl;
|
||||
p = ped.m_Extent;
|
||||
INFO << "extent " << p.x << " " << p.y << " " << p.z << std::endl;
|
||||
for (int i=0; i < 4; i++) {
|
||||
for (int j=0; j < 4; j++) {
|
||||
std::cout << "M " << ped.m_M.m[i][j] << " ";
|
||||
|
||||
if (ped.isLineInBox( pos, new_pos ) ) {
|
||||
Vector3D p;
|
||||
ped.lineCrossBox(pos, new_pos, p);
|
||||
float angle = Util::xz_angle(Vector3D(0,0,0), p);
|
||||
INFO << angle << std::endl;
|
||||
if (angle <= 90.0f || angle > 270.0f)
|
||||
INFO << "FRONT" << std::endl;
|
||||
else
|
||||
INFO << "BACK" << std::endl;
|
||||
ped.getShot(owner, Projectile::damageByType(typeId), true);
|
||||
PlayerController & pc = LocalPlayer::Instance();
|
||||
if (owner == pc.getId()) {
|
||||
pc.addCash(10);
|
||||
pc.addWanted(1);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}*/
|
||||
|
||||
|
||||
if (ped.IsLineInBox( pos, new_pos ) ) {
|
||||
INFO << "HIT ped " << ped.id() << std::endl;
|
||||
ped.getShot(true);
|
||||
//ped.sprType = GraphicsBase::SpriteNumbers::OBJECT;
|
||||
//ped.remap = -1;
|
||||
//SpriteManagerHolder::Instance().removePed(ped.pedId);
|
||||
endsAtTick = 0;
|
||||
}
|
||||
}
|
||||
std::list<Car> & clist = SpriteManagerHolder::Instance().getList<Car>();
|
||||
for (std::list<Car>::iterator i = clist.begin(); i != clist.end(); i++) {
|
||||
Car & car = *i;
|
||||
|
||||
if (car.isLineInBox(pos, new_pos)) {
|
||||
INFO << "CAR HIT" << std::endl;
|
||||
Vector3D p;
|
||||
car.lineCrossBox(pos, new_pos, p);
|
||||
car.damageAt(p, 5);
|
||||
//INFO << Util::xz_angle(Vector3D(0,0,0), p) << std::endl;
|
||||
delta = Vector3D(0, 0, 0);
|
||||
p = Transform(p, car.m_M);
|
||||
new_pos.x = p.x;
|
||||
new_pos.z = p.z;
|
||||
new_pos.y += 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Util::CellIterator oi(pos);
|
||||
|
||||
Util::CellIterator ni(new_pos);
|
||||
//FIXME ni valid?
|
||||
|
||||
if (oi.isValid() && ni.isValid()) {
|
||||
if (oi == ni) { // only one cell to check
|
||||
Math::line_intersect(pos, new_pos);//, oi.getBlock());
|
||||
int collided = 0;
|
||||
if (oi.isValid()) {
|
||||
Map::BlockInfo & bi = oi.getBlock();
|
||||
if (bi.isFlat()) {
|
||||
collided += testCollideBlock_flat(oi, new_pos);
|
||||
}
|
||||
else { // crosses cell boundary
|
||||
Math::line_intersect(pos, new_pos);//, oi.getBlock());
|
||||
//Math::line_intersect(pos, new_pos);//, ni.getBlock());
|
||||
Util::CellIterator ni(oi.right());
|
||||
if (ni.isValid())
|
||||
collided += testCollideBlock(ni, new_pos);
|
||||
ni = oi.left();
|
||||
if (ni.isValid())
|
||||
collided += testCollideBlock(ni, new_pos);
|
||||
ni = oi.top();
|
||||
if (ni.isValid())
|
||||
collided += testCollideBlock(ni, new_pos);
|
||||
ni = oi.bottom();
|
||||
if (ni.isValid())
|
||||
collided += testCollideBlock(ni, new_pos);
|
||||
}
|
||||
}
|
||||
else
|
||||
INFO << "NEITHER VALID!"<< oi.x << " " << oi.y << " " << oi.z <<std::endl;
|
||||
*/
|
||||
if (collided)
|
||||
delta = Vector3D(0, 0, 0);
|
||||
pos = new_pos;
|
||||
|
||||
lastUpdateAt = ticks;
|
||||
}
|
||||
|
||||
uint32_t Projectile::damageByType(const uint8_t & k) {
|
||||
uint32_t v = 7;
|
||||
switch(k) {
|
||||
case 2:
|
||||
v = 150;
|
||||
break;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "cell_iterator.h"
|
||||
#include "entity_controller.h"
|
||||
#include "OpenSteer/Proximity.h"
|
||||
#include "util/set.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
|
||||
@ -90,20 +91,70 @@ namespace OpenGTA {
|
||||
bool inGroundContact;
|
||||
void tryMove(Vector3D nPos);
|
||||
uint8_t isDead;
|
||||
void getShot(bool front = true);
|
||||
void getShot(uint32_t shooterId, uint32_t dmg, bool front = true);
|
||||
void die();
|
||||
typedef std::map<uint8_t, uint32_t> InventoryMap;
|
||||
InventoryMap inventory;
|
||||
uint8_t activeWeapon;
|
||||
uint32_t * activeAmmo;
|
||||
uint32_t aiMode;
|
||||
static uint32_t fistAmmo;
|
||||
struct AiData {
|
||||
AiData() : id1(0), id2(0), pos1() {}
|
||||
AiData(const AiData & o) : id1(o.id1), id2(o.id2), pos1(o.pos1) {}
|
||||
uint32_t id1;
|
||||
uint32_t id2;
|
||||
Vector3D pos1;
|
||||
};
|
||||
AiData aiData;
|
||||
Vector3D moveDelta;
|
||||
};
|
||||
|
||||
class Car : public GameObject_common, public Sprite, public OBox {
|
||||
class CarSprite {
|
||||
public:
|
||||
class DoorDeltaAnimation : public Util::Animation {
|
||||
public:
|
||||
DoorDeltaAnimation(uint8_t dId, bool dOpen);
|
||||
uint8_t doorId;
|
||||
bool opening;
|
||||
};
|
||||
CarSprite();
|
||||
CarSprite(Uint16 sprN, Sint16 rem, GraphicsBase::SpriteNumbers::SpriteTypes sprT);
|
||||
CarSprite(const CarSprite & o);
|
||||
Uint16 sprNum;
|
||||
Sint16 remap;
|
||||
GraphicsBase::SpriteNumbers::SpriteTypes sprType;
|
||||
uint32_t delta;
|
||||
Util::Set deltaSet;
|
||||
Util::Set animState;
|
||||
void setDamage(uint8_t k);
|
||||
void openDoor(uint8_t k);
|
||||
void closeDoor(uint8_t k);
|
||||
void setSirenAnim(bool on);
|
||||
bool assertDeltaById(uint8_t k);
|
||||
void update(Uint32 ticks);
|
||||
private:
|
||||
typedef std::list<DoorDeltaAnimation> DoorAnimList;
|
||||
DoorAnimList doorAnims;
|
||||
Uint32 lt_siren;
|
||||
};
|
||||
|
||||
class Car : public GameObject_common, public CarSprite, public OBox {
|
||||
public:
|
||||
Car(const Car & o);
|
||||
Car(OpenGTA::Map::ObjectPosition&, uint32_t id);
|
||||
Car(Vector3D & _pos, float _rot, uint32_t id, uint8_t _type, int16_t _remap = -1);
|
||||
uint32_t carId;
|
||||
inline uint32_t id() const { return carId; }
|
||||
GraphicsBase::CarInfo & carInfo;
|
||||
uint8_t type;
|
||||
void update(Uint32 ticks);
|
||||
Uint32 lastUpdateAt;
|
||||
void damageAt(const Vector3D & hit, uint32_t dmg);
|
||||
void explode();
|
||||
private:
|
||||
void fixSpriteType();
|
||||
int32_t hitPoints;
|
||||
};
|
||||
|
||||
class SpriteObject : public GameObject_common, public Sprite, public OBox {
|
||||
@ -139,6 +190,9 @@ namespace OpenGTA {
|
||||
uint32_t owner;
|
||||
void update(Uint32 ticks);
|
||||
Uint32 lastUpdateAt;
|
||||
bool testCollideBlock(Util::CellIterator &, Vector3D & newp);
|
||||
bool testCollideBlock_flat(Util::CellIterator &, Vector3D & newp);
|
||||
static uint32_t damageByType(const uint8_t & k);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -78,12 +78,12 @@ namespace OpenGL {
|
||||
OpenGTA::Map::BlockInfo * block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
||||
if (block->blockType() > 0 && block->blockType() <= 5) {
|
||||
float bz = slope_height_offset(block->slopeType(), eye.x - x, eye.z - z);
|
||||
if (block->slopeType() == 0 && block->blockType() != 5)
|
||||
if (block->slopeType() == 0 && (block->blockType() != 5 && block->blockType() != 6))
|
||||
bz -= 1;
|
||||
//INFO << int(block->blockType()) << ", " << eye.y << ", " <<
|
||||
// eye.y - y << ", " << eye.y - y - bz << ", " << bz << std::endl;
|
||||
float react_delta = 0.3f;
|
||||
if (block->blockType() == 5)
|
||||
if (block->blockType() == 5 || block->blockType() == 6)
|
||||
react_delta = 0.0f;
|
||||
if (eye.y - y - bz < react_delta) {
|
||||
//do_grav = 0;
|
||||
@ -109,7 +109,7 @@ namespace OpenGL {
|
||||
y -= 1;
|
||||
if (y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z)) && y > 0.0f) {
|
||||
OpenGTA::Map::BlockInfo * block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
||||
if (block->blockType() == 5) {
|
||||
if (block->blockType() == 5 || block->blockType() == 6) {
|
||||
float bz = slope_height_offset(block->slopeType(), eye.x - x, eye.z - z);
|
||||
//INFO << eye.y << ", " << y << " bz " << bz << std::endl;
|
||||
if (eye.y - y - bz < 0.4f) {
|
||||
|
175
gl_cityview.cpp
175
gl_cityview.cpp
@ -35,6 +35,8 @@
|
||||
#include "blockdata.h"
|
||||
#include "image_loader.h"
|
||||
#include "blockanim.h"
|
||||
#include "id_sys.h"
|
||||
#include "map_helper.h"
|
||||
|
||||
float slope_height_offset(unsigned char slope_type, float dx, float dz);
|
||||
namespace OpenGTA {
|
||||
@ -72,6 +74,33 @@ namespace OpenGTA {
|
||||
return tex;
|
||||
}
|
||||
*/
|
||||
struct GLColor {
|
||||
GLfloat rgb[3];
|
||||
GLColor() { rgb[0] = rgb[1] = rgb[2] = 0; }
|
||||
GLColor(GLfloat i) { rgb[0] = rgb[1] = rgb[2] = i; }
|
||||
GLColor(GLfloat r, GLfloat g, GLfloat b) { rgb[0] = r; rgb[1] = g; rgb[2] = b; }
|
||||
};
|
||||
|
||||
GLColor block_colors[8] = {
|
||||
GLColor(1), // air
|
||||
GLColor(0, 0, 1), // water
|
||||
GLColor(0, 1, 1), // road
|
||||
GLColor(1, 0, 0), // pavement
|
||||
GLColor(0, 1, 0), // field
|
||||
GLColor(1, 1, 0), // building
|
||||
GLColor(1), // unused
|
||||
GLColor(1) // unused
|
||||
};
|
||||
|
||||
GLfloat* map_block_type_color(uint8_t k) {
|
||||
// k = 6 now used to fix pavement cols
|
||||
if (k == 7)
|
||||
WARN << "block-type: " << int(k) << " should be unused!" << std::endl;
|
||||
if (k < 8)
|
||||
return block_colors[k].rgb;
|
||||
ERROR << "Invalid block-type: " << int(k) << std::endl;
|
||||
return block_colors[0].rgb;
|
||||
}
|
||||
|
||||
CityView::CityView() {
|
||||
setNull();
|
||||
@ -95,6 +124,7 @@ namespace OpenGTA {
|
||||
topDownView = true;
|
||||
drawTextured = true;
|
||||
drawLines = false;
|
||||
drawLinesBlockType = true;
|
||||
setPosition(0.0f, 0.0f, 20.0f);
|
||||
|
||||
scene_display_list = 0;
|
||||
@ -119,8 +149,10 @@ namespace OpenGTA {
|
||||
}
|
||||
bool CityView::getDrawTextured() { return drawTextured; }
|
||||
bool CityView::getDrawLines() { return drawLines; }
|
||||
bool CityView::getDrawLinesBlockColor() { return drawLinesBlockType; }
|
||||
void CityView::setDrawTextured(bool v) { drawTextured = v; }
|
||||
void CityView::setDrawLines(bool v) { drawLines= v; }
|
||||
void CityView::setDrawLinesBlockColor(bool v) { drawLinesBlockType= v; }
|
||||
void CityView::cleanup() {
|
||||
//if (loadedMap)
|
||||
// delete loadedMap;
|
||||
@ -146,6 +178,7 @@ namespace OpenGTA {
|
||||
loadedMap = &MapHolder::Instance().get();
|
||||
StyleHolder::Instance().load(style_f);
|
||||
style = &StyleHolder::Instance().get();
|
||||
style->setDeltaHandling(true);
|
||||
/*
|
||||
for (size_t i = 0; i < style->carInfos.size(); ++i) {
|
||||
OpenGTA::GraphicsBase::CarInfo * cinfo = style->carInfos[i];
|
||||
@ -166,23 +199,33 @@ namespace OpenGTA {
|
||||
scene_display_list = glGenLists(1);
|
||||
|
||||
SpriteManagerHolder::Instance().clear();
|
||||
|
||||
// safeguard against double car entries (in nyc.cmp)
|
||||
Util::MapOfPair2Int d_car_map;
|
||||
for (PHYSFS_uint16 oc = 0; oc < loadedMap->numObjects; oc++) {
|
||||
OpenGTA::Map::ObjectPosition & op = loadedMap->objects[oc];
|
||||
if (op.remap >= 128) {
|
||||
if (Util::item_count(d_car_map, op.x, op.y) == 0)
|
||||
Util::register_item1(d_car_map, op.x, op.y);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
createLevelObject(&loadedMap->objects[oc]);
|
||||
}
|
||||
//SpriteManagerHolder::Instance().trainSystem.loadStations(*loadedMap);
|
||||
activeRect.x = activeRect.y = 0;
|
||||
activeRect.w = activeRect.h = 0;
|
||||
}
|
||||
void CityView::createLevelObject(OpenGTA::Map::ObjectPosition *obj) {
|
||||
SpriteManager & s_man = SpriteManagerHolder::Instance();
|
||||
uint32_t id = TypeIdBlackBox::requestId();
|
||||
if (obj->remap >= 128) {
|
||||
Car car(*obj, 0);
|
||||
Car car(*obj, id);
|
||||
s_man.add(car);
|
||||
//s_man.addCar(car);
|
||||
}
|
||||
else {
|
||||
//GameObject gobj(*obj);
|
||||
SpriteObject gobj(*obj, 0);
|
||||
SpriteObject gobj(*obj, id);
|
||||
s_man.add(gobj);
|
||||
//s_man.addObject(gobj);
|
||||
}
|
||||
}
|
||||
void CityView::setZoom(const GLfloat zoom) {
|
||||
@ -232,6 +275,7 @@ namespace OpenGTA {
|
||||
int yi = int(z);
|
||||
//int zi = int(z);
|
||||
float h = 0.5f;
|
||||
WARN << "THIS FUNCTION SHOULD NOT BE USED!" << std::endl;
|
||||
PHYSFS_uint16 emptycount = loadedMap->getNumBlocksAt(xi, yi);
|
||||
for (int c=6-emptycount; c >= 1; c--) {
|
||||
OpenGTA::Map::BlockInfo* bi = loadedMap->getBlockAt(xi, yi, c);
|
||||
@ -250,14 +294,56 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
OpenGL::PagedTexture CityView::renderMap2Texture() {
|
||||
uint32_t width = OpenGL::ScreenHolder::Instance().getWidth();
|
||||
uint32_t height = OpenGL::ScreenHolder::Instance().getHeight();
|
||||
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||
uint32_t width = screen.getWidth();
|
||||
uint32_t height = screen.getHeight();
|
||||
|
||||
uint32_t gl_h = 1;
|
||||
while (gl_h < height)
|
||||
gl_h <<= 1;
|
||||
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glFinish();
|
||||
Vector3D v_off(0,0,0);
|
||||
int persp_find_done = 0;
|
||||
int break_loop_safe = 500;
|
||||
while (persp_find_done != 3) {
|
||||
OpenGL::ScreenHolder::Instance().set3DProjection();
|
||||
glRotatef(180, 0, 0, 1);
|
||||
gluLookAt(128, 230, 128, 128, 0, 128, 0.0f, 0.0f, 1.0f);
|
||||
glTranslatef(-42, 0, 0);
|
||||
|
||||
gluLookAt(128+v_off.x, 230, 128+v_off.y, 128+v_off.x, 0, 128+v_off.y, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
GLint viewport[4];
|
||||
GLdouble mvmatrix[16], projmatrix[16];
|
||||
GLdouble winx, winy, winz;
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix);
|
||||
glGetDoublev (GL_PROJECTION_MATRIX, projmatrix);
|
||||
gluProject(0, 0, 0, mvmatrix, projmatrix, viewport, &winx, &winy, &winz);
|
||||
if (winx > 0.5f)
|
||||
v_off.x += 0.2f;
|
||||
else if (winx < -0.5f)
|
||||
v_off.x -= 0.2f;
|
||||
else
|
||||
persp_find_done |= 1;
|
||||
INFO << winx << " " << winy << std::endl;
|
||||
gluProject(256, 0, 256, mvmatrix, projmatrix, viewport, &winx, &winy, &winz);
|
||||
if (winy < -0.5f)
|
||||
v_off.y += 0.2f;
|
||||
else if (winy > 0.5f)
|
||||
v_off.y -= 0.2f;
|
||||
else
|
||||
persp_find_done |= 2;
|
||||
break_loop_safe--;
|
||||
if (break_loop_safe == 0) {
|
||||
WARN << "breaking out of loop - NOT GOOD!" << std::endl;
|
||||
persp_find_done = 3;
|
||||
}
|
||||
INFO << winx << " " << winy << std::endl;
|
||||
}
|
||||
|
||||
//glTranslatef(-35, 0, 0);
|
||||
for (int i = 0; i <= 255; i++) {
|
||||
for (int j= 0; j <= 255; j++) {
|
||||
glPushMatrix();
|
||||
@ -274,16 +360,27 @@ namespace OpenGTA {
|
||||
}
|
||||
GL_CHECKERROR;
|
||||
|
||||
uint32_t gl_h = 1;
|
||||
while (gl_h < height)
|
||||
gl_h <<= 1;
|
||||
glFinish();
|
||||
/*
|
||||
GLuint txtnumber;
|
||||
glGenTextures(1, &txtnumber); // Create 1 Texture
|
||||
glBindTexture(GL_TEXTURE_2D, txtnumber); // Bind The Texture
|
||||
GL_CHECKERROR;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, gl_h, gl_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
GL_CHECKERROR;
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width/2, height/2);
|
||||
GL_CHECKERROR;
|
||||
//glViewport(0, 0, width, height);
|
||||
return OpenGL::PagedTexture(txtnumber, 0, 0, 1, 1);
|
||||
*/
|
||||
uint32_t img_size = gl_h * gl_h * 3;
|
||||
uint8_t *img_buf = Util::BufferCacheHolder::Instance().requestBuffer(img_size);
|
||||
|
||||
glReadBuffer(GL_BACK);
|
||||
for (uint32_t i = 0; i < gl_h; i++) {
|
||||
glReadPixels(0, i, gl_h, 1, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)(img_buf + gl_h * 3 * i));
|
||||
}
|
||||
//for (uint32_t i = 0; i < gl_h; i++) {
|
||||
// glReadPixels(0, i, gl_h, 1, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)(img_buf + gl_h * 3 * i));
|
||||
//}
|
||||
glReadPixels(0, 0, gl_h, gl_h, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img_buf);
|
||||
GL_CHECKERROR;
|
||||
|
||||
sideCache->sink();
|
||||
@ -295,12 +392,26 @@ namespace OpenGTA {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
uint32_t y_off = 100;
|
||||
uint32_t x = 0;
|
||||
while (*(img_buf + y_off * gl_h * 3 + x) == 0 && *(img_buf + y_off * gl_h * 3 + x+1) == 0 &&
|
||||
*(img_buf + y_off * gl_h * 3 + x + 2) == 0)
|
||||
x += 3;
|
||||
INFO << "color after x = " << x/3 << std::endl;
|
||||
x = gl_h-3;
|
||||
while (*(img_buf + y_off * gl_h * 3 + x) == 0 && *(img_buf + y_off * gl_h * 3 + x+1) == 0 &&
|
||||
*(img_buf + y_off * gl_h * 3 + x+2) == 0)
|
||||
x -= 3;
|
||||
INFO << "color after x = " << x/3 << std::endl;
|
||||
|
||||
|
||||
GLuint tex = ImageUtil::createGLTexture(gl_h, gl_h, false, img_buf);
|
||||
float f_h = float(height) / gl_h;
|
||||
float f_w = float(width) / gl_h;
|
||||
//float horiz_corr = (1.0f - f_w) / 2.0f;
|
||||
//return OpenGL::PagedTexture(tex, 0+horiz_corr, 0, f_w+horiz_corr, f_h);
|
||||
return OpenGL::PagedTexture(tex, 0, 0, f_w, f_h);
|
||||
|
||||
return OpenGL::PagedTexture(tex, 0, 0, f_h, f_h);
|
||||
}
|
||||
|
||||
void CityView::draw(Uint32 ticks) {
|
||||
@ -363,6 +474,8 @@ namespace OpenGTA {
|
||||
if (y2 > 255)
|
||||
y2 = 255;
|
||||
|
||||
//INFO << activeRect.x << ", " << activeRect.y << " -> " <<
|
||||
// activeRect.x+activeRect.w << ", " << activeRect.y + activeRect.h << std::endl;
|
||||
activeRect.x = x1;
|
||||
activeRect.y = y1;
|
||||
activeRect.w = x2 - x1;
|
||||
@ -405,6 +518,12 @@ namespace OpenGTA {
|
||||
for (int c=0; c < maxcount; ++c) {
|
||||
++scene_rendered_blocks;
|
||||
glPushMatrix();
|
||||
if (c < maxcount - 1) {
|
||||
Map::BlockInfo * bi = loadedMap->getBlockAtNew(j, i, c + 1);
|
||||
aboveBlockType = bi->blockType();
|
||||
}
|
||||
else
|
||||
aboveBlockType = loadedMap->getBlockAtNew(j, i, c)->blockType();
|
||||
drawBlock(loadedMap->getBlockAtNew(j, i, c));
|
||||
glPopMatrix();
|
||||
glTranslatef(0.0f, 1.0f, 0.0f);
|
||||
@ -712,6 +831,14 @@ namespace OpenGTA {
|
||||
}
|
||||
}
|
||||
|
||||
#define RESET_COLOR glColor3f(1, 1, 1)
|
||||
#define COLOR_OFF if (drawLinesBlockType) RESET_COLOR
|
||||
#define COLOR_BY_BLOCK(idx) { GLfloat *_c = map_block_type_color(idx); glColor3f(_c[0], _c[1], _c[2]); }
|
||||
#define COLOR_ON if (drawLinesBlockType) COLOR_BY_BLOCK(aboveBlockType)
|
||||
//#define COLOR_ON if (drawLinesBlockType) COLOR_BY_BLOCK(bi->blockType())
|
||||
|
||||
if (drawLinesBlockType)
|
||||
|
||||
// handle flat/transparent case
|
||||
if (is_flat) {
|
||||
if (bi->lid) {
|
||||
@ -738,6 +865,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][0][j][0],
|
||||
@ -750,6 +878,7 @@ namespace OpenGTA {
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
COLOR_OFF;
|
||||
}
|
||||
}
|
||||
#undef MSWAP
|
||||
@ -790,6 +919,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][2][j][0],
|
||||
@ -810,6 +940,7 @@ namespace OpenGTA {
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
COLOR_OFF;
|
||||
}
|
||||
}
|
||||
jj = 0;
|
||||
@ -848,6 +979,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][3][j][0],
|
||||
@ -866,6 +998,7 @@ namespace OpenGTA {
|
||||
SLOPE_RAW_DATA[which][4][0][1],
|
||||
SLOPE_RAW_DATA[which][4][0][2]);
|
||||
glEnd();
|
||||
COLOR_OFF;
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
}
|
||||
@ -896,6 +1029,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][0][j][0],
|
||||
@ -908,6 +1042,7 @@ namespace OpenGTA {
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
COLOR_OFF;
|
||||
}
|
||||
}
|
||||
jj = 0; // only 'lid' rotated
|
||||
@ -947,6 +1082,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][2][j][0],
|
||||
@ -959,6 +1095,7 @@ namespace OpenGTA {
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
COLOR_OFF;
|
||||
}
|
||||
}
|
||||
jj = 0;
|
||||
@ -989,6 +1126,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][1][j][0],
|
||||
@ -1001,6 +1139,7 @@ namespace OpenGTA {
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
COLOR_OFF;
|
||||
}
|
||||
}
|
||||
/*memcpy(sideTex1, sideTex1_bak, 8 * sizeof(GLfloat));
|
||||
@ -1037,6 +1176,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][3][j][0],
|
||||
@ -1049,6 +1189,7 @@ namespace OpenGTA {
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
COLOR_OFF;
|
||||
}
|
||||
}
|
||||
jj = 0;
|
||||
@ -1079,6 +1220,7 @@ namespace OpenGTA {
|
||||
// lines
|
||||
if (drawLines) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
COLOR_ON;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][4][j][0],
|
||||
@ -1091,6 +1233,7 @@ namespace OpenGTA {
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// end-of-lines
|
||||
COLOR_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,10 +54,12 @@ namespace OpenGTA {
|
||||
NavData::Sector* getCurrentSector();
|
||||
OpenGL::PagedTexture renderMap2Texture();
|
||||
|
||||
bool CityView::getDrawTextured();
|
||||
bool CityView::getDrawLines();
|
||||
void CityView::setDrawTextured(bool v);
|
||||
void CityView::setDrawLines(bool v);
|
||||
bool getDrawTextured();
|
||||
bool getDrawLines();
|
||||
bool getDrawLinesBlockColor();
|
||||
void setDrawTextured(bool v);
|
||||
void setDrawLines(bool v);
|
||||
void setDrawLinesBlockColor(bool v);
|
||||
|
||||
void resetTextures();
|
||||
const SDL_Rect & getActiveRect() { return activeRect; }
|
||||
@ -83,6 +85,9 @@ namespace OpenGTA {
|
||||
bool topDownView;
|
||||
bool drawTextured;
|
||||
bool drawLines;
|
||||
bool drawLinesBlockType;
|
||||
bool drawHeadingMarkers;
|
||||
uint8_t aboveBlockType;
|
||||
|
||||
SDL_Rect activeRect;
|
||||
SDL_Rect drawnRect;
|
||||
@ -92,7 +97,6 @@ namespace OpenGTA {
|
||||
|
||||
GLuint scene_display_list;
|
||||
bool scene_is_dirty;
|
||||
bool drawHeadingMarkers;
|
||||
int texFlipTest;
|
||||
|
||||
Uint32 lastCacheEmptyTicks;
|
||||
|
28
gl_font.cpp
28
gl_font.cpp
@ -95,6 +95,34 @@ namespace OpenGL {
|
||||
return move;
|
||||
}
|
||||
|
||||
GLfloat DrawableFont::drawString_r2l(const std::string & text) {
|
||||
assert(texCache != NULL);
|
||||
assert(fontSource != NULL);
|
||||
std::string::const_reverse_iterator i = text.rbegin();
|
||||
std::string::const_reverse_iterator e = text.rend();
|
||||
GLfloat move = 0.0f;
|
||||
while (i != e) {
|
||||
|
||||
if (*i != ' ') {
|
||||
FontQuad* character = NULL;
|
||||
std::map<char, FontQuad*>::const_iterator j = drawables.find(*i);
|
||||
if (j == drawables.end()) {
|
||||
character = createDrawableCharacter(*i);
|
||||
drawables[*i] = character;
|
||||
}
|
||||
else {
|
||||
GLfloat mm = float(fontSource->getMoveWidth(*i)) * 1.1f * scale;
|
||||
glTranslatef(-mm, 0.0f, 0.0f);
|
||||
character = j->second;
|
||||
move += mm;
|
||||
}
|
||||
Renderer<FontQuad>::draw(*character);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return move;
|
||||
}
|
||||
|
||||
uint16_t DrawableFont::getHeight() {
|
||||
return scale * fontSource->getCharHeight();
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ namespace OpenGL {
|
||||
~DrawableFont();
|
||||
void loadFont(const std::string & filename);
|
||||
GLfloat drawString(const std::string & text) ;
|
||||
GLfloat drawString_r2l(const std::string & text) ;
|
||||
void setScale(unsigned int newScale);
|
||||
uint16_t getHeight();
|
||||
void resetTextures();
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "log.h"
|
||||
#include "buffercache.h"
|
||||
#include "m_exceptions.h"
|
||||
#include "image_loader.h"
|
||||
|
||||
namespace OpenGL {
|
||||
#ifndef DEFAULT_SCREEN_WIDTH
|
||||
@ -32,6 +33,9 @@ namespace OpenGL {
|
||||
#endif
|
||||
#ifndef DEFAULT_SCREEN_HEIGHT
|
||||
#define DEFAULT_SCREEN_HEIGHT 480
|
||||
#endif
|
||||
#ifndef DEFAULT_SCREEN_VSYNC
|
||||
#define DEFAULT_SCREEN_VSYNC 0
|
||||
#endif
|
||||
|
||||
Screen::Screen() {
|
||||
@ -43,6 +47,8 @@ namespace OpenGL {
|
||||
fieldOfView = 60.0f;
|
||||
nearPlane = 0.1f;
|
||||
farPlane = 250.0f;
|
||||
// 0: no vsync, 1: sdl, 2 native
|
||||
useVsync = DEFAULT_SCREEN_VSYNC;
|
||||
}
|
||||
|
||||
void Screen::activate(Uint32 w, Uint32 h) {
|
||||
@ -52,6 +58,7 @@ namespace OpenGL {
|
||||
height = h;
|
||||
initSDL();
|
||||
resize(width, height);
|
||||
INFO << "activating screen: " << width << "x" << height << std::endl;
|
||||
initGL();
|
||||
setSystemMouseCursor(false);
|
||||
}
|
||||
@ -62,6 +69,10 @@ namespace OpenGL {
|
||||
farPlane = far_p;
|
||||
}
|
||||
|
||||
void Screen::setupVsync(size_t mode) {
|
||||
useVsync = mode;
|
||||
}
|
||||
|
||||
void Screen::setSystemMouseCursor(bool visible) {
|
||||
SDL_ShowCursor((visible ? SDL_ENABLE : SDL_DISABLE));
|
||||
}
|
||||
@ -112,7 +123,7 @@ namespace OpenGL {
|
||||
|
||||
const char* sdl_err = SDL_GetError();
|
||||
if (strlen(sdl_err) > 0)
|
||||
INFO << "sdl_init complained: " << sdl_err << std::endl;
|
||||
WARN << "SDL_Init complained: " << sdl_err << std::endl;
|
||||
SDL_ClearError();
|
||||
|
||||
const SDL_VideoInfo *vInfo = SDL_GetVideoInfo();
|
||||
@ -166,33 +177,75 @@ namespace OpenGL {
|
||||
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
|
||||
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);
|
||||
#ifdef HAVE_SDL_VSYNC
|
||||
if (useVsync == 1) {
|
||||
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1);
|
||||
INFO << "enabling vertical sync:" << " SDL" << std::endl;
|
||||
}
|
||||
#else
|
||||
if (useVsync == 1)
|
||||
WARN << "Cannot use SDL vsync - option disabled while compiling" << std::endl;
|
||||
#endif
|
||||
|
||||
sdl_err = SDL_GetError();
|
||||
if (strlen(sdl_err) > 0)
|
||||
ERROR << "setting sdl_gl attributes: " << sdl_err << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void Screen::initGL() {
|
||||
GL_CHECKERROR;
|
||||
//GLfloat LightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f };
|
||||
//GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
//GLfloat LightPosition[] = { 128.0f, 200.0f, 128.0f, 1.0f };
|
||||
|
||||
if (useVsync == 2) {
|
||||
#ifdef LINUX
|
||||
int (*fp)(int) = (int(*)(int)) SDL_GL_GetProcAddress("glXSwapIntervalMESA");
|
||||
if (fp) {
|
||||
fp(1);
|
||||
INFO << "enabling vertical sync:" << " GLX" << std::endl;
|
||||
}
|
||||
else
|
||||
ERROR << "No symbol 'glXSwapIntervalMESA' found - cannot use GLX vsync" << std::endl;
|
||||
#else
|
||||
typedef void (APIENTRY * WGLSWAPINTERVALEXT) (int);
|
||||
WGLSWAPINTERVALEXT wglSwapIntervalEXT =
|
||||
(WGLSWAPINTERVALEXT) wglGetProcAddress("wglSwapIntervalEXT");
|
||||
if (wglSwapIntervalEXT)
|
||||
{
|
||||
wglSwapIntervalEXT(1); // set vertical synchronisation
|
||||
INFO << "enabling vertical sync:" << " WGL" << std::endl;
|
||||
}
|
||||
else
|
||||
ERROR << "No symbol 'wglSwapIntervalEXT' found - cannot use WGL vsync" << std::endl;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
GLfloat LightAmbient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
GLfloat LightPosition[] = { 1.0f, 1.0f, 0.0f, 0.0f };
|
||||
*/
|
||||
//glShadeModel( GL_SMOOTH );
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
//glEnable( GL_LIGHTING );
|
||||
/*
|
||||
glEnable( GL_LIGHTING );
|
||||
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
|
||||
//glLightfv( GL_LIGHT0, GL_AMBIENT, LightAmbient );
|
||||
//glLightfv( GL_LIGHT0, GL_DIFFUSE, LightDiffuse );
|
||||
//glLightfv( GL_LIGHT0, GL_POSITION, LightPosition );
|
||||
//glEnable( GL_LIGHT0 );
|
||||
glLightfv( GL_LIGHT0, GL_AMBIENT, LightAmbient );
|
||||
glLightfv( GL_LIGHT0, GL_DIFFUSE, LightDiffuse );
|
||||
glLightfv( GL_LIGHT0, GL_POSITION, LightPosition );
|
||||
glEnable( GL_LIGHT0 );
|
||||
*/
|
||||
glEnable( GL_COLOR_MATERIAL);
|
||||
glCullFace(GL_BACK);
|
||||
//glPolygonMode(GL_FRONT, GL_FILL);
|
||||
//glPolygonMode(GL_BACK, GL_LINE);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (queryExtension("GL_EXT_texture_filter_anisotropic")) {
|
||||
GLfloat maxAniso = 1.0f;
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
|
||||
//if (maxAniso >= 2.0f)
|
||||
ImageUtil::supportedMaxAnisoDegree = maxAniso;
|
||||
INFO << "GL supports anisotropic filtering with degree: " << maxAniso << std::endl;
|
||||
}
|
||||
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
|
||||
@ -256,4 +309,18 @@ namespace OpenGL {
|
||||
SDL_SaveBMP(image, filename);
|
||||
SDL_FreeSurface( image );
|
||||
}
|
||||
|
||||
GLboolean Screen::queryExtension(const char *extName) {
|
||||
// from the 'Red Book'
|
||||
char *p = (char *) glGetString(GL_EXTENSIONS);
|
||||
char *end = p + strlen(p);
|
||||
while (p < end) {
|
||||
size_t n = strcspn(p, " ");
|
||||
if ((strlen(extName)==n) && (strncmp(extName,p,n)==0)) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
p += (n + 1);
|
||||
}
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,9 @@ namespace OpenGL {
|
||||
inline float getNearPlane() { return nearPlane; }
|
||||
inline float getFarPlane() { return farPlane; }
|
||||
void setupGlVars( float fov, float near_p, float far_p);
|
||||
void setupVsync( size_t enabled );
|
||||
|
||||
static GLboolean queryExtension(const char *extName);
|
||||
|
||||
private:
|
||||
void initGL();
|
||||
@ -55,6 +58,7 @@ namespace OpenGL {
|
||||
Uint32 width, height;
|
||||
Uint32 bpp;
|
||||
Uint32 videoFlags;
|
||||
size_t useVsync;
|
||||
float fieldOfView;
|
||||
float nearPlane;
|
||||
float farPlane;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <cassert>
|
||||
#include <SDL_image.h>
|
||||
#include "gl_spritecache.h"
|
||||
#include "image_loader.h"
|
||||
#include "opengta.h"
|
||||
#include "dataholder.h"
|
||||
#include "buffercache.h"
|
||||
@ -188,8 +189,6 @@ namespace OpenGL {
|
||||
INFO << "creating new sprite: " << sprite_num << " remap: " << remap << std::endl;
|
||||
unsigned char* src = OpenGTA::StyleHolder::Instance().get().
|
||||
getSpriteBitmap(sprite_num, remap , delta);
|
||||
unsigned int glwidth = 1;
|
||||
unsigned int glheight = 1;
|
||||
#if 0
|
||||
if (sprite_num == 257) {
|
||||
info->w = 72;
|
||||
@ -210,6 +209,9 @@ namespace OpenGL {
|
||||
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
int glwidth = 1;
|
||||
int glheight = 1;
|
||||
|
||||
while(glwidth < info->w)
|
||||
glwidth <<= 1;
|
||||
@ -225,8 +227,21 @@ namespace OpenGL {
|
||||
t += glwidth * 4;
|
||||
r += info->w * 4;
|
||||
}
|
||||
#endif
|
||||
ImageUtil::NextPowerOfTwo npot(info->w, info->h);
|
||||
Util::BufferCache & bc = Util::BufferCacheHolder::Instance();
|
||||
uint8_t* dst = bc.requestBuffer(npot.w * npot.h * 4);
|
||||
|
||||
ImageUtil::copyImage2Image(dst, src, info->w * 4, info->h, npot.w * 4);
|
||||
bc.unlockBuffer(src);
|
||||
|
||||
#ifdef DO_SCALE2X
|
||||
if (doScale2x) {
|
||||
bc.lockBuffer(dst);
|
||||
uint8_t* dst_scalex = ImageUtil::scale2x_32bit(dst, npot.w, npot.h);
|
||||
bc.unlockBuffer(dst);
|
||||
dst = dst_scalex;
|
||||
#if 0
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
@ -236,9 +251,9 @@ namespace OpenGL {
|
||||
Util::BufferCacheHolder::Instance().lockBuffer(dst);
|
||||
Uint8* dstpix = Util::BufferCacheHolder::Instance().requestBuffer(glwidth * glheight * 4 * 4);
|
||||
Uint32 E0, E1, E2, E3, B, D, E, F, H;
|
||||
for(unsigned int looph = 0; looph < glheight; ++looph)
|
||||
for(int looph = 0; looph < glheight; ++looph)
|
||||
{
|
||||
for(unsigned int loopw = 0; loopw < glwidth; ++ loopw)
|
||||
for(int loopw = 0; loopw < glwidth; ++ loopw)
|
||||
{
|
||||
B = *(Uint32*)(srcpix + (MAX(0,looph-1)*srcpitch) + (4*loopw));
|
||||
D = *(Uint32*)(srcpix + (looph*srcpitch) + (4*MAX(0,loopw-1)));
|
||||
@ -259,10 +274,14 @@ namespace OpenGL {
|
||||
}
|
||||
Util::BufferCacheHolder::Instance().unlockBuffer(dst);
|
||||
dst = dstpix;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
GLuint texid;
|
||||
GLuint texid = (doScale2x) ?
|
||||
ImageUtil::createGLTexture(npot.w * 2, npot.h * 2, true, dst)
|
||||
: ImageUtil::createGLTexture(npot.w, npot.h, true, dst);
|
||||
#if 0
|
||||
glGenTextures(1, &texid);
|
||||
glBindTexture(GL_TEXTURE_2D, texid);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
@ -276,9 +295,11 @@ namespace OpenGL {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glwidth, glheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, dst);
|
||||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glwidth, glheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, dst);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return OpenGL::PagedTexture(texid, 0, 0,
|
||||
float(info->w)/float(glwidth), float(info->h)/float(glheight));
|
||||
float(info->w)/float(npot.w), float(info->h)/float(npot.h));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
************************************************************************/
|
||||
#ifndef SPRITE_CACHE_H
|
||||
#define SPRITE_CACHE_H
|
||||
#include <cstddef>
|
||||
#include <physfs.h>
|
||||
#include "Singleton.h"
|
||||
#include "gl_pagedtexture.h"
|
||||
@ -65,7 +66,7 @@ namespace OpenGL {
|
||||
OpenGTA::GraphicsBase::SpriteNumbers::SpriteTypes,
|
||||
PHYSFS_sint16 remap, PHYSFS_uint32 delta);
|
||||
|
||||
OpenGL::PagedTexture SpriteCache::createSprite(size_t sprite_num, PHYSFS_sint16 remap,
|
||||
OpenGL::PagedTexture createSprite(size_t sprite_num, PHYSFS_sint16 remap,
|
||||
PHYSFS_uint32 delta, OpenGTA::GraphicsBase::SpriteInfo* info);
|
||||
private:
|
||||
|
||||
|
@ -63,6 +63,11 @@ these remain under their respective licenses.
|
||||
Copyright (C) 2000 Amir Geva
|
||||
GNU Library General Public License
|
||||
|
||||
* Oriented bounding box derived from code originally written by
|
||||
Jonathan Kreuzer
|
||||
http://www.3dkingdoms.com/
|
||||
No license given by original author; derived code under zlib license.
|
||||
|
||||
***************************************************************************
|
||||
Please do not redistribute the data files of the original game together
|
||||
with this software.
|
||||
|
69
localplayer.cpp
Normal file
69
localplayer.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "localplayer.h"
|
||||
#include "spritemanager.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
Pedestrian & PlayerController::getPed() {
|
||||
return SpriteManagerHolder::Instance().getPed(playerId);
|
||||
}
|
||||
|
||||
bool PlayerController::up(const uint32_t & key) {
|
||||
if (!pc_ptr)
|
||||
return false;
|
||||
bool handled = false;
|
||||
switch (key) {
|
||||
case SDLK_LEFT:
|
||||
pc_ptr->releaseTurnLeft();
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
pc_ptr->releaseTurnRight();
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
pc_ptr->releaseMoveForward();
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
pc_ptr->releaseMoveBack();
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
pc_ptr->releaseFireWeapon();
|
||||
handled = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool PlayerController::down(const uint32_t & key) {
|
||||
if (!pc_ptr)
|
||||
return false;
|
||||
bool handled = false;
|
||||
switch(key) {
|
||||
case SDLK_LEFT:
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
handled = true;
|
||||
break;
|
||||
case SDLK_LSHIFT:
|
||||
handled = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
}
|
@ -4,13 +4,21 @@
|
||||
#include "game_objects.h"
|
||||
#include "entity_controller.h"
|
||||
#include "id_sys.h"
|
||||
#include "key_handler.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
|
||||
class PlayerController { // : public PedController { //public Pedestrian::Controller {
|
||||
class PlayerController : public Util::KeyHandler {
|
||||
public:
|
||||
PlayerController() {
|
||||
reset();
|
||||
}
|
||||
void reset() {
|
||||
playerId = TypeIdBlackBox::getPlayerId();
|
||||
cash = 0;
|
||||
wantedLevel = 0;
|
||||
modifier = 0;
|
||||
numLives = 0;
|
||||
pc_ptr = NULL;
|
||||
}
|
||||
PedController & getCtrl() {
|
||||
@ -20,8 +28,27 @@ namespace OpenGTA {
|
||||
void setCtrl(PedController & pc) {
|
||||
pc_ptr = &pc;
|
||||
}
|
||||
void giveLives(uint16_t k) {
|
||||
numLives += k;
|
||||
}
|
||||
void disableCtrl(bool soft);
|
||||
void enableCtrl();
|
||||
Pedestrian & getPed();
|
||||
int32_t getNumLives() { return numLives; }
|
||||
int32_t getWantedLevel() { return wantedLevel; }
|
||||
uint32_t getCash() { return cash; }
|
||||
bool up(const uint32_t & key);
|
||||
bool down(const uint32_t & key);
|
||||
uint32_t getId() { return playerId; }
|
||||
void addCash(uint32_t v) { cash += v; }
|
||||
void setWanted(int32_t v) { wantedLevel = v; }
|
||||
void addWanted(uint32_t v) { wantedLevel += v; if (wantedLevel > 5) wantedLevel = 5; }
|
||||
private:
|
||||
uint32_t playerId;
|
||||
uint32_t cash;
|
||||
int32_t wantedLevel;
|
||||
uint32_t modifier;
|
||||
int32_t numLives;
|
||||
PedController * pc_ptr;
|
||||
};
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <cassert>
|
||||
#include "lua_ini_bridge.h"
|
||||
#include "log.h"
|
||||
|
||||
|
150
lua_addon/lua_map.cpp
Normal file
150
lua_addon/lua_map.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include "lua_map.h"
|
||||
#include "m_exceptions.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
namespace Script {
|
||||
int Block::l_getBlockType(lua_State *L) {
|
||||
lua_pushinteger(L, blockType());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_setBlockType(lua_State *L) {
|
||||
uint8_t v = luaL_checkinteger(L, 1);
|
||||
setBlockType(v);
|
||||
return 0;
|
||||
}
|
||||
int Block::l_getSlopeType(lua_State *L) {
|
||||
lua_pushinteger(L, slopeType());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_setSlopeType(lua_State *L) {
|
||||
uint8_t v = luaL_checkinteger(L, 1);
|
||||
setSlopeType(v);
|
||||
return 0;
|
||||
}
|
||||
int Block::l_getRotation(lua_State *L) {
|
||||
lua_pushinteger(L, rotation());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_setRotation(lua_State *L) {
|
||||
uint8_t v = luaL_checkinteger(L, 1);
|
||||
setRotation(v);
|
||||
return 0;
|
||||
}
|
||||
int Block::l_getUpOk(lua_State *L) {
|
||||
lua_pushboolean(L, upOk());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getDownOk(lua_State *L) {
|
||||
lua_pushboolean(L, downOk());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getLeftOk(lua_State *L) {
|
||||
lua_pushboolean(L, leftOk());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getRightOk(lua_State *L) {
|
||||
lua_pushboolean(L, rightOk());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getIsFlat(lua_State *L) {
|
||||
lua_pushboolean(L, isFlat());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getRailway(lua_State *L) {
|
||||
lua_pushboolean(L, railway());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getRailStation(lua_State *L) {
|
||||
lua_pushboolean(L, railStation());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getRailStationTrain(lua_State *L) {
|
||||
lua_pushboolean(L, railStationTrain());
|
||||
return 1;
|
||||
}
|
||||
int Block::l_getTextureId(lua_State *L) {
|
||||
int which = luaL_checkinteger(L, 1);
|
||||
int v = 0;
|
||||
if ((which < 0) || (which > 4)) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "Quad id " << which << " is invalid";
|
||||
throw E_OUTOFRANGE(ostr.str());
|
||||
}
|
||||
switch(which) {
|
||||
case 0:
|
||||
v = lid;
|
||||
break;
|
||||
case 1:
|
||||
v = top;
|
||||
break;
|
||||
case 2:
|
||||
v = bottom;
|
||||
break;
|
||||
case 3:
|
||||
v = left;
|
||||
break;
|
||||
case 4:
|
||||
v = right;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// handled above
|
||||
}
|
||||
lua_pushinteger(L, v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LMap::l_getBlockAt(lua_State *L) {
|
||||
int x, y, z;
|
||||
x = luaL_checkinteger(L, 1);
|
||||
y = luaL_checkinteger(L, 2);
|
||||
z = luaL_checkinteger(L, 3);
|
||||
OpenGTA::Map::BlockInfo* bi = getBlockAtNew(x, y, z);
|
||||
assert(bi);
|
||||
Block* b = static_cast<Block*>(bi);
|
||||
Lunar<Block>::push(L, b, false);
|
||||
return 1;
|
||||
}
|
||||
int LMap::l_getNumBlocksAt(lua_State *L) {
|
||||
int x, y;
|
||||
x = luaL_checkinteger(L, 1);
|
||||
y = luaL_checkinteger(L, 2);
|
||||
lua_pushinteger(L, getNumBlocksAtNew(x, y));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char Block::className[] = "Block";
|
||||
#define method(name) {#name, &Block::l_##name}
|
||||
Lunar<Block>::RegType Block::methods[] = {
|
||||
method(getBlockType),
|
||||
method(getSlopeType),
|
||||
method(getRotation),
|
||||
method(getIsFlat),
|
||||
method(getLeftOk),
|
||||
method(getRightOk),
|
||||
method(getUpOk),
|
||||
method(getDownOk),
|
||||
method(getRailway),
|
||||
method(getRailStation),
|
||||
method(getRailStationTrain),
|
||||
method(getTextureId),
|
||||
|
||||
method(setBlockType),
|
||||
method(setRotation),
|
||||
method(setSlopeType),
|
||||
{0, 0}
|
||||
};
|
||||
#undef method
|
||||
#define method(name) {#name, &LMap::l_##name}
|
||||
const char LMap::className[] = "Map";
|
||||
Lunar<LMap>::RegType LMap::methods[] = {
|
||||
method(getNumBlocksAt),
|
||||
method(getBlockAt),
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
50
lua_addon/lua_map.h
Normal file
50
lua_addon/lua_map.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef LUA_MAP_H
|
||||
#define LUA_MAP_H
|
||||
|
||||
#include "lunar.h"
|
||||
#include "opengta.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
namespace Script {
|
||||
class Block : public OpenGTA::Map::BlockInfo {
|
||||
public:
|
||||
int l_getBlockType(lua_State *L);
|
||||
int l_getUpOk(lua_State *L);
|
||||
int l_getDownOk(lua_State *L);
|
||||
int l_getLeftOk(lua_State *L);
|
||||
int l_getRightOk(lua_State *L);
|
||||
int l_getIsFlat(lua_State *L);
|
||||
int l_getSlopeType(lua_State *L);
|
||||
int l_getRotation(lua_State *L);
|
||||
int l_getRailway(lua_State *L);
|
||||
int l_getRailStation(lua_State *L);
|
||||
int l_getRailStationTrain(lua_State *L);
|
||||
int l_getTextureId(lua_State *L);
|
||||
|
||||
int l_setBlockType(lua_State *L);
|
||||
int l_setUpOk(lua_State *L);
|
||||
int l_setDownOk(lua_State *L);
|
||||
int l_setLeftOk(lua_State *L);
|
||||
int l_setRightOk(lua_State *L);
|
||||
int l_setIsFlat(lua_State *L);
|
||||
int l_setSlopeType(lua_State *L);
|
||||
int l_setRotation(lua_State *L);
|
||||
//...
|
||||
int l_setTextureId(lua_State *L);
|
||||
|
||||
|
||||
static const char className[];
|
||||
static Lunar<Block>::RegType methods[];
|
||||
};
|
||||
class LMap : public OpenGTA::Map {
|
||||
public:
|
||||
LMap() : OpenGTA::Map("") {}
|
||||
int l_getNumBlocksAt(lua_State *L);
|
||||
int l_getBlockAt(lua_State *L);
|
||||
|
||||
static const char className[];
|
||||
static Lunar<LMap>::RegType methods[];
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
@ -11,6 +11,8 @@
|
||||
|
||||
using namespace Util;
|
||||
|
||||
extern int global_Done;
|
||||
|
||||
namespace OpenGTA {
|
||||
namespace Script {
|
||||
LuaVM::LuaVM() : L(NULL) {
|
||||
@ -20,6 +22,7 @@ namespace OpenGTA {
|
||||
|
||||
luaopen_base(L);
|
||||
luaopen_math(L);
|
||||
luaopen_table(L);
|
||||
_registered = false;
|
||||
lua_settop(L, 0);
|
||||
prepare();
|
||||
@ -31,17 +34,24 @@ namespace OpenGTA {
|
||||
L = NULL;
|
||||
}
|
||||
|
||||
int vm_quit(lua_State *L) {
|
||||
global_Done = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LuaVM::prepare() {
|
||||
LGUARD(L);
|
||||
if (!_registered) {
|
||||
Lunar<Block>::Register2(L);
|
||||
Lunar<LMap>::Register2(L);
|
||||
/*
|
||||
#ifndef LUA_MAP_ONLY
|
||||
Lunar<CityView>::Register2(L);
|
||||
luaL_openlib(L, "camera", Camera::methods, 0);
|
||||
luaL_openlib(L, "screen", Screen::methods, 0);
|
||||
luaL_openlib(L, "spritecache", SpriteCache::methods, 0);
|
||||
*/
|
||||
#endif
|
||||
lua_pushcfunction(L, vm_quit);
|
||||
lua_setglobal(L, "quit");
|
||||
}
|
||||
_registered = true;
|
||||
}
|
||||
@ -61,15 +71,15 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
void LuaVM::setCityView(OpenGTA::CityView & cv) {
|
||||
#ifndef LUA_MAP_ONLY
|
||||
LGUARD(L);
|
||||
/*
|
||||
CityView *scv = static_cast<CityView*>(&cv);
|
||||
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||
int scv_ref = Lunar<CityView>::push(L, scv, false);
|
||||
lua_pushliteral(L, "city_view");
|
||||
lua_pushvalue(L, scv_ref);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
void LuaVM::runString(const char* _str) {
|
||||
@ -103,7 +113,7 @@ namespace OpenGTA {
|
||||
lua_getglobal(L, key);
|
||||
if (!lua_isnumber(L, -1))
|
||||
throw E_SCRIPTERROR("Expected int value for key: " + std::string(key));
|
||||
int v = int(lua_tonumber(L, -1));
|
||||
int v = int(lua_tointeger(L, -1));
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -125,9 +135,69 @@ namespace OpenGTA {
|
||||
return v;
|
||||
}
|
||||
|
||||
bool LuaVM::getGlobalBool(const char* key) {
|
||||
LGUARD(L);
|
||||
lua_getglobal(L, key);
|
||||
if (!lua_isboolean(L, -1))
|
||||
throw E_SCRIPTERROR("Expected boolean value for key: " + std::string(key));
|
||||
return lua_toboolean(L, -1);
|
||||
}
|
||||
|
||||
void LuaVM::setInt(const char* key, int v) {
|
||||
lua_pushinteger(L, v);
|
||||
lua_setfield(L, -2, key);
|
||||
}
|
||||
|
||||
int LuaVM::getInt(const char* key) {
|
||||
LGUARD(L);
|
||||
lua_getfield(L, -1, key);
|
||||
if (!lua_isnumber(L, -1))
|
||||
throw E_SCRIPTERROR("Expected int value for key: " + std::string(key));
|
||||
return luaL_checkinteger(L, -1);
|
||||
}
|
||||
|
||||
void LuaVM::setFloat(const char* key, float v) {
|
||||
lua_pushnumber(L, v);
|
||||
lua_setfield(L, -2, key);
|
||||
}
|
||||
|
||||
float LuaVM::getFloat(const char* key) {
|
||||
LGUARD(L);
|
||||
lua_getfield(L, -1, key);
|
||||
if (!lua_isnumber(L, -1))
|
||||
throw E_SCRIPTERROR("Expected float value for key: " + std::string(key));
|
||||
return luaL_checknumber(L, -1);
|
||||
}
|
||||
|
||||
void LuaVM::setString(const char* key, const char* v) {
|
||||
lua_pushstring(L, v);
|
||||
lua_setfield(L, -2, key);
|
||||
}
|
||||
|
||||
const char* LuaVM::getString(const char* key) {
|
||||
LGUARD(L);
|
||||
lua_getfield(L, -1, key);
|
||||
if (!lua_isstring(L, -1))
|
||||
throw E_SCRIPTERROR("Expected string value for key: " + std::string(key));
|
||||
return luaL_checkstring(L, -1);
|
||||
}
|
||||
|
||||
void LuaVM::setBool(const char* key, bool v) {
|
||||
lua_pushboolean(L, v);
|
||||
lua_setfield(L, -2, key);
|
||||
}
|
||||
|
||||
bool LuaVM::getBool(const char* key) {
|
||||
LGUARD(L);
|
||||
lua_getfield(L, -1, key);
|
||||
if (!lua_isboolean(L, -1))
|
||||
throw E_SCRIPTERROR("Expected boolean value for key: " + std::string(key));
|
||||
return lua_toboolean(L, -1);
|
||||
}
|
||||
|
||||
void LuaVM::setGlobalInt(const char* key, int v) {
|
||||
LGUARD(L);
|
||||
lua_pushnumber(L, v);
|
||||
lua_pushinteger(L, v);
|
||||
lua_setglobal(L, key);
|
||||
}
|
||||
|
||||
@ -143,5 +213,11 @@ namespace OpenGTA {
|
||||
lua_setglobal(L, key);
|
||||
}
|
||||
|
||||
void LuaVM::setGlobalBool(const char* key, bool v) {
|
||||
LGUARD(L);
|
||||
lua_pushboolean(L, v);
|
||||
lua_setglobal(L, key);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,21 @@ namespace OpenGTA {
|
||||
int getGlobalInt(const char*);
|
||||
float getGlobalFloat(const char*);
|
||||
const char* getGlobalString(const char*);
|
||||
bool getGlobalBool(const char*);
|
||||
void setGlobalInt(const char*, int);
|
||||
void setGlobalFloat(const char*, float);
|
||||
void setGlobalString(const char*, const char*);
|
||||
void setGlobalBool(const char*, bool);
|
||||
|
||||
void setInt(const char*, int);
|
||||
int getInt(const char*);
|
||||
void setFloat(const char*, float);
|
||||
float getFloat(const char*);
|
||||
void setString(const char*, const char*);
|
||||
const char* getString(const char*);
|
||||
void setBool(const char*, bool);
|
||||
bool getBool(const char*);
|
||||
|
||||
lua_State *getInternalState();
|
||||
protected:
|
||||
lua_State *L;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include "m_exceptions.h"
|
||||
#include "log.h"
|
||||
|
||||
@ -11,6 +12,7 @@ extern void run_main();
|
||||
|
||||
int global_EC = 0;
|
||||
int global_Done = 0;
|
||||
int global_Restart = 0;
|
||||
|
||||
#ifndef DONT_CATCH
|
||||
bool catch_exceptions = true;
|
||||
@ -54,5 +56,10 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
}
|
||||
if (global_Restart) {
|
||||
on_exit();
|
||||
execvp(argv[0], argv);
|
||||
}
|
||||
|
||||
std::exit(0);
|
||||
}
|
||||
|
3
makefile
3
makefile
@ -58,7 +58,8 @@ doxy_main.h: doc/hacking.txt tools/doxy_doc.sh
|
||||
doxyclean:
|
||||
$(RM) doxy_main.h -r doc/html
|
||||
|
||||
package:
|
||||
package: release_files_sorted
|
||||
sh tools/cvslog.sh
|
||||
(cd .. && tar jvcf ogta_src_`date +%F`.tar.bz2 -T ogta/release_files_sorted)
|
||||
@echo "saved as: ogta_src_`date +%F.tar.bz2`"
|
||||
|
||||
|
@ -1,4 +1,46 @@
|
||||
/* Derived from code written by Jonathan Kreuzer.
|
||||
*
|
||||
* See: http://www.3dkingdoms.com/weekly/weekly.php?a=21
|
||||
*
|
||||
* basically the same as bbox.h/.cpp but using coldet math
|
||||
*
|
||||
* -- quote from a mail of the author --
|
||||
*
|
||||
* You're free to continue using my CBBox code however you want.
|
||||
* ... [snip] ...
|
||||
* The only thing I ask is a note about where it came from ( I think
|
||||
* you said you added a link to the article, so that's fine. )
|
||||
*
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
|
||||
#include <cassert>
|
||||
#include "log.h"
|
||||
#include "obox.h"
|
||||
|
||||
#include "plane.h"
|
||||
// --------------------------
|
||||
//
|
||||
// Oriented Bounding Box Class
|
||||
@ -8,7 +50,7 @@
|
||||
//
|
||||
// Check if a point is in this bounding box
|
||||
//
|
||||
bool OBox::IsPointInBox(const Vector3D &InP) const
|
||||
bool OBox::isPointInBox(const Vector3D &InP) const
|
||||
{
|
||||
// Rotate the point into the box's coordinates
|
||||
Vector3D P = Transform(InP, m_M.Inverse());
|
||||
@ -23,7 +65,7 @@ bool OBox::IsPointInBox(const Vector3D &InP) const
|
||||
//
|
||||
// Check if a sphere overlaps any part of this bounding box
|
||||
//
|
||||
bool OBox::IsSphereInBox( const Vector3D &InP, float fRadius) const
|
||||
bool OBox::isSphereInBox( const Vector3D &InP, float fRadius) const
|
||||
{
|
||||
float fDist;
|
||||
float fDistSq = 0;
|
||||
@ -44,7 +86,7 @@ bool OBox::IsSphereInBox( const Vector3D &InP, float fRadius) const
|
||||
//
|
||||
// Check if the bounding box is completely behind a plane( defined by a normal and a point )
|
||||
//
|
||||
bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP ) const
|
||||
bool OBox::boxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP ) const
|
||||
{
|
||||
// Plane Normal in Box Space
|
||||
Vector3D Norm = rotateVector(InNorm, m_M.Inverse() );
|
||||
@ -52,7 +94,7 @@ bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP ) const
|
||||
|
||||
float Extent = Norm * m_Extent; //Norm.Dot( m_Extent ); // Box Extent along the plane normal
|
||||
//float Distance = InNorm.Dot( GetCenterPoint() - InP ); // Distance from Box Center to the Plane
|
||||
float Distance = InNorm * (GetCenterPoint() - InP);
|
||||
float Distance = InNorm * (getCenterPoint() - InP);
|
||||
|
||||
// If Box Centerpoint is behind the plane further than its extent, the Box is outside the plane
|
||||
if ( Distance < -Extent ) return true;
|
||||
@ -62,7 +104,7 @@ bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP ) const
|
||||
//
|
||||
// Does the Line (L1, L2) intersect the Box?
|
||||
//
|
||||
bool OBox::IsLineInBox( const Vector3D& L1, const Vector3D& L2 ) const
|
||||
bool OBox::isLineInBox( const Vector3D& L1, const Vector3D& L2 ) const
|
||||
{
|
||||
// Put line in box space
|
||||
Matrix3D MInv = m_M.Inverse();
|
||||
@ -87,10 +129,40 @@ bool OBox::IsLineInBox( const Vector3D& L1, const Vector3D& L2 ) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void OBox::lineCrossBox(const Vector3D& L1, const Vector3D& L2, Vector3D & isecLocal) const {
|
||||
// Put line in box space
|
||||
Matrix3D MInv = m_M.Inverse();
|
||||
Vector3D LB1 = Transform(L1, MInv);
|
||||
Vector3D LB2 = Transform(L2, MInv);
|
||||
float small_t = 2.0f;
|
||||
Vector3D p_copy(0, 0, 0);
|
||||
|
||||
//i = 0: -x,-z <-> -x,z
|
||||
//i = 1: -x,-z <-> x,-z
|
||||
//i = 2: x,-z, <-> x,z
|
||||
//i = 3: -x,z <-> x,z
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Vector3D s1((i <= 1 || i == 3 ? -m_Extent.x : m_Extent.x), 0, (i < 3 ? -m_Extent.z : m_Extent.z));
|
||||
Vector3D s2((i == 0 ? -m_Extent.x : m_Extent.x), 0, (i == 1 ? -m_Extent.z : m_Extent.z));
|
||||
Vector3D p;
|
||||
float dt = Math::intersection_segments(s1, s2, LB1, LB2, p);
|
||||
if ((dt >= 0.0f) && (dt < small_t)) {
|
||||
p_copy = p;
|
||||
small_t = dt;
|
||||
}
|
||||
}
|
||||
if (small_t >= 0.0f && small_t <= 1.0f) {
|
||||
isecLocal = p_copy;
|
||||
return;
|
||||
}
|
||||
ERROR << "Did not find intersection when OBB says there is one :-(" << std::endl;
|
||||
isecLocal = L1;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns a 3x3 rotation matrix as vectors
|
||||
//
|
||||
inline void OBox::GetInvRot( Vector3D *pvRot ) const
|
||||
inline void OBox::getInvRot( Vector3D *pvRot ) const
|
||||
{
|
||||
pvRot[0] = Vector3D( m_M.m[0][0], m_M.m[0][1], m_M.m[0][2] );
|
||||
pvRot[1] = Vector3D( m_M.m[1][0], m_M.m[1][1], m_M.m[1][2] );
|
||||
@ -101,13 +173,13 @@ inline void OBox::GetInvRot( Vector3D *pvRot ) const
|
||||
// Check if any part of a box is inside any part of another box
|
||||
// Uses the separating axis test.
|
||||
//
|
||||
bool OBox::IsBoxInBox( OBox &BBox ) const
|
||||
bool OBox::isBoxInBox( OBox &BBox ) const
|
||||
{
|
||||
Vector3D SizeA = m_Extent;
|
||||
Vector3D SizeB = BBox.m_Extent;
|
||||
Vector3D RotA[3], RotB[3];
|
||||
GetInvRot( RotA );
|
||||
BBox.GetInvRot( RotB );
|
||||
getInvRot( RotA );
|
||||
BBox.getInvRot( RotB );
|
||||
|
||||
float R[3][3]; // Rotation from B to A
|
||||
float AR[3][3]; // absolute values of R matrix, to use with box extents
|
||||
@ -123,7 +195,7 @@ bool OBox::IsBoxInBox( OBox &BBox ) const
|
||||
}
|
||||
|
||||
// Vector separating the centers of Box B and of Box A
|
||||
Vector3D vSepWS = BBox.GetCenterPoint() - GetCenterPoint();
|
||||
Vector3D vSepWS = BBox.getCenterPoint() - getCenterPoint();
|
||||
// Rotated into Box A's coordinates
|
||||
Vector3D vSepA( vSepWS * RotA[0], vSepWS * RotA[1], vSepWS * RotA[2] );
|
||||
|
||||
|
70
math/obox.h
70
math/obox.h
@ -1,43 +1,79 @@
|
||||
/* Derived from code written by Jonathan Kreuzer.
|
||||
*
|
||||
* See: http://www.3dkingdoms.com/weekly/weekly.php?a=21
|
||||
*
|
||||
* basically the same as bbox.h/.cpp but using coldet math
|
||||
*
|
||||
* -- quote from a mail of the author --
|
||||
*
|
||||
* You're free to continue using my CBBox code however you want.
|
||||
* ... [snip] ...
|
||||
* The only thing I ask is a note about where it came from ( I think
|
||||
* you said you added a link to the article, so that's fine. )
|
||||
*
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
|
||||
#include "math3d.h"
|
||||
|
||||
// see: from: http://www.3dkingdoms.com/weekly/weekly.php?a=21
|
||||
|
||||
// basically the same as bbox.h/.cpp but using coldet math
|
||||
|
||||
class OBox
|
||||
{
|
||||
public:
|
||||
OBox() {}
|
||||
OBox( const Matrix3D & m, const Vector3D & extent )
|
||||
{ Set( m, extent ); }
|
||||
{ set( m, extent ); }
|
||||
OBox( const Matrix3D & m, const Vector3D & low, const Vector3D & high )
|
||||
{ Set( m, low, high ); }
|
||||
{ set( m, low, high ); }
|
||||
OBox( const OBox & other)
|
||||
{ Set( other.m_M, other.m_Extent ); }
|
||||
{ set( other.m_M, other.m_Extent ); }
|
||||
|
||||
void Set( const Matrix3D & m, const Vector3D & extent )
|
||||
void set( const Matrix3D & m, const Vector3D & extent )
|
||||
{
|
||||
m_M = m;
|
||||
m_Extent = extent;
|
||||
}
|
||||
void Set( const Matrix3D & m, const Vector3D & low, const Vector3D & high )
|
||||
void set( const Matrix3D & m, const Vector3D & low, const Vector3D & high )
|
||||
{
|
||||
m_M = m;
|
||||
m_M.Translate( 0.5f * (low + high) );
|
||||
m_Extent = 0.5f * (high - low);
|
||||
}
|
||||
|
||||
Vector3D GetSize() const
|
||||
Vector3D getSize() const
|
||||
{ return 2.0f * m_Extent; }
|
||||
Vector3D GetCenterPoint() const
|
||||
Vector3D getCenterPoint() const
|
||||
{ return m_M.GetTranslate(); }
|
||||
void GetInvRot( Vector3D *pvRot ) const;
|
||||
void getInvRot( Vector3D *pvRot ) const;
|
||||
|
||||
bool IsPointInBox( const Vector3D & p ) const ;
|
||||
bool IsBoxInBox( OBox & box ) const ;
|
||||
bool IsSphereInBox( const Vector3D & p, float fRadius ) const ;
|
||||
bool IsLineInBox( const Vector3D & l1, const Vector3D & l2 ) const ;
|
||||
bool BoxOutsidePlane( const Vector3D & normal, const Vector3D & p ) const ;
|
||||
bool isPointInBox( const Vector3D & p ) const ;
|
||||
bool isBoxInBox( OBox & box ) const ;
|
||||
bool isSphereInBox( const Vector3D & p, float fRadius ) const ;
|
||||
bool isLineInBox( const Vector3D & l1, const Vector3D & l2 ) const ;
|
||||
bool boxOutsidePlane( const Vector3D & normal, const Vector3D & p ) const ;
|
||||
|
||||
void lineCrossBox(const Vector3D & l1, const Vector3D & l2, Vector3D & isecLocalSpace) const;
|
||||
|
||||
// Data
|
||||
Matrix3D m_M;
|
||||
|
74
math/plane.cpp
Normal file
74
math/plane.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include "plane.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace Math {
|
||||
|
||||
// see: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/example.cpp
|
||||
float intersection_segments(const Vector3D & s1, const Vector3D & s2,
|
||||
const Vector3D & l1, const Vector3D & l2, Vector3D & hit) {
|
||||
float denom = (l2.z - l1.z) * (s2.x - s1.x) -
|
||||
(l2.x - l1.x) * (s2.z - s1.z);
|
||||
|
||||
float d_a = (l2.x - l1.x) * (s1.z - l1.z) -
|
||||
(l2.z - l1.z) * (s1.x - l1.x);
|
||||
|
||||
float d_b = (s2.x - s1.x) * (s1.z - l1.z) -
|
||||
(s2.z - s1.z) * (s1.x - l1.x);
|
||||
|
||||
float ua = d_a / denom; // ratio on s1 -> s2
|
||||
float ub = d_b / denom; // ratio on l1 -> l2
|
||||
|
||||
if (denom == 0.0f) {
|
||||
/*
|
||||
if (d_a == 0.0f && d_b == 0.0f)
|
||||
INFO << "COINCIDENT" << std::endl;
|
||||
else
|
||||
INFO << "PARALLEL" << std::endl;
|
||||
*/
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
|
||||
hit.x = s1.x + ua * (s2.x - s1.x);
|
||||
hit.z = s1.z + ua * (s2.z - s1.z);
|
||||
//INFO << "INTERSECTING " << hit.x << " " << hit.z << std::endl;
|
||||
//INFO << ua << " | " << ub << std::endl;
|
||||
return ub;
|
||||
}
|
||||
//INFO << "NOT INTERSECTING" << std::endl;
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
int Plane::segmentIntersect(const Vector3D & p1, const Vector3D & p2, Vector3D & p_p) {
|
||||
float d = - normal.x * pop.x - normal.y * pop.y - normal.z * pop.z;
|
||||
float denom = normal.x * (p2.x - p1.x) + normal.y * (p2.y - p1.y) +
|
||||
normal.z * (p2.z - p1.z);
|
||||
if (fabs(denom) < 0.001f)
|
||||
return false;
|
||||
float mu = - (d + normal.x * p1.x + normal.y * p1.y + normal.z * p1.z) / denom;
|
||||
p_p = Vector3D(p2 - p1) * mu + p1;
|
||||
if (mu < 0 || mu > 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
float Plane::distance(const Vector3D & p) {
|
||||
float d = normal * p;
|
||||
d += - normal.x * pop.x - normal.y * pop.y - normal.z * pop.z;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
int main() {
|
||||
Vector3D p(0, 0, 0);
|
||||
Vector3D n(-1, 0, 0);
|
||||
Math::Plane plane(p, n);
|
||||
Vector3D p1(-1, 0, 0);
|
||||
Vector3D p2(1, 0, 0);
|
||||
Vector3D col;
|
||||
if (plane.segmentIntersect(p1, p2, col))
|
||||
std::cout << "intersect at: " << col.x << " " << col.y << " " << col.z << std::endl;
|
||||
std::cout << plane.distance(p1) << std::endl;
|
||||
std::cout << plane.distance(p2) << std::endl;
|
||||
}
|
||||
*/
|
26
math/plane.h
Normal file
26
math/plane.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef MATH_PLANE_H
|
||||
#define MATH_PLANE_H
|
||||
|
||||
#include "math3d.h"
|
||||
|
||||
namespace Math {
|
||||
|
||||
float intersection_segments(const Vector3D & s1, const Vector3D & s2,
|
||||
const Vector3D & l1, const Vector3D & l2, Vector3D & hit);
|
||||
|
||||
struct Plane {
|
||||
Plane(const Vector3D & p, const Vector3D & n) :
|
||||
pop(p), normal(n) {}
|
||||
Plane(const Vector3D & p1, const Vector3D & p2, const Vector3D & p3) :
|
||||
pop(p1), normal() {
|
||||
const Vector3D pa(p2 - p1);
|
||||
const Vector3D pb(p3 - p1);
|
||||
normal = CrossProduct(pa, pb).Normalized();
|
||||
}
|
||||
Vector3D pop;
|
||||
Vector3D normal;
|
||||
int segmentIntersect(const Vector3D & p1, const Vector3D & p2, Vector3D & p_p);
|
||||
float distance(const Vector3D & p);
|
||||
};
|
||||
}
|
||||
#endif
|
47
navdata.cpp
47
navdata.cpp
@ -100,28 +100,48 @@ namespace OpenGTA {
|
||||
return "";
|
||||
std::string n;
|
||||
if (lastSubLocation == 0)
|
||||
n.append("Central ");
|
||||
//n.append("Central ");
|
||||
n.append(_c);
|
||||
else if (lastSubLocation == 1)
|
||||
n.append("North ");
|
||||
//n.append("North ");
|
||||
n.append(_n);
|
||||
else if (lastSubLocation == 2)
|
||||
n.append("South ");
|
||||
n.append(_s);
|
||||
//n.append("South ");
|
||||
else if (lastSubLocation == 4)
|
||||
n.append("East ");
|
||||
n.append(_e);
|
||||
//n.append("East ");
|
||||
else if (lastSubLocation == 8)
|
||||
n.append("West ");
|
||||
n.append(_w);
|
||||
//n.append("West ");
|
||||
else if (lastSubLocation == 9)
|
||||
n.append("Northwest ");
|
||||
n.append(_nw);
|
||||
//n.append("Northwest ");
|
||||
else if (lastSubLocation == 10)
|
||||
n.append("Southwest ");
|
||||
n.append(_sw);
|
||||
//n.append("Southwest ");
|
||||
else if (lastSubLocation == 5)
|
||||
n.append("Northeast ");
|
||||
n.append(_ne);
|
||||
//n.append("Northeast ");
|
||||
else if (lastSubLocation == 6)
|
||||
n.append("Southeast ");
|
||||
n.append(_se);
|
||||
//n.append("Southeast ");
|
||||
|
||||
n.append(" ");
|
||||
n.append(name);
|
||||
return n.c_str();
|
||||
}
|
||||
|
||||
std::string NavData::_c;
|
||||
std::string NavData::_n;
|
||||
std::string NavData::_s;
|
||||
std::string NavData::_w;
|
||||
std::string NavData::_e;
|
||||
std::string NavData::_nw;
|
||||
std::string NavData::_ne;
|
||||
std::string NavData::_sw;
|
||||
std::string NavData::_se;
|
||||
|
||||
NavData::NavData(PHYSFS_uint32 size, PHYSFS_file *fd, const size_t level_num) {
|
||||
if (size % 35) {
|
||||
std::ostringstream o;
|
||||
@ -133,6 +153,15 @@ namespace OpenGTA {
|
||||
assert(fd);
|
||||
|
||||
MessageDB & msg = MainMsgHolder::Instance().get();
|
||||
_c =msg.getText("c");
|
||||
_n = msg.getText("n");
|
||||
_s = msg.getText("s");
|
||||
_w = msg.getText("w");
|
||||
_e = msg.getText("e");
|
||||
_nw = msg.getText("nw");
|
||||
_ne = msg.getText("ne");
|
||||
_sw = msg.getText("sw");
|
||||
_se = msg.getText("se");
|
||||
for (PHYSFS_uint32 i = 0; i < c; ++i) {
|
||||
Sector *sec = new Sector(fd);
|
||||
if (sec->getSize() == 0) { // workaround for 'NYC.CMP' (empty sectors)
|
||||
|
@ -89,6 +89,7 @@ namespace OpenGTA {
|
||||
NavData(PHYSFS_uint32 size, PHYSFS_file *fd, const size_t level_num);
|
||||
~NavData();
|
||||
Sector* getSectorAt(PHYSFS_uint8, PHYSFS_uint8);
|
||||
static std::string _c, _n, _s, _w, _e, _nw, _ne, _sw, _se;
|
||||
private:
|
||||
void clear();
|
||||
typedef std::multimap<PHYSFS_uint16, Sector*> SectorMapType;
|
||||
|
@ -1 +1 @@
|
||||
2007-04-16
|
||||
2007-06-14
|
||||
|
25
opengta.h
25
opengta.h
@ -27,6 +27,7 @@ namespace OpenGTA {
|
||||
public:
|
||||
GraphicsBase();
|
||||
virtual ~GraphicsBase();
|
||||
uint8_t getFormat();
|
||||
|
||||
typedef struct ObjectInfo {
|
||||
PHYSFS_uint32 width, height, depth;
|
||||
@ -399,11 +400,15 @@ namespace OpenGTA {
|
||||
inline bool downOk() { return (typeMap & 2); }
|
||||
inline bool leftOk() { return (typeMap & 4); }
|
||||
inline bool rightOk() { return (typeMap & 8); }
|
||||
inline uint8_t blockType() { return ((typeMap & 16 ? 1 : 0) + (typeMap & 32 ? 2 : 0) + (typeMap & 64 ? 4 : 0)); }
|
||||
inline uint8_t blockType() { return ((typeMap & 16 ? 1 : 0) +
|
||||
(typeMap & 32 ? 2 : 0) + (typeMap & 64 ? 4 : 0)); }
|
||||
inline bool isFlat() { return (typeMap & 128); }
|
||||
inline uint8_t slopeType() { return ((typeMap & 256 ? 1 : 0) + (typeMap & 512 ? 2 : 0) +
|
||||
(typeMap & 1024 ? 4 : 0) + (typeMap & 2048 ? 8 : 0) + (typeMap & 4096 ? 16 : 0) + (typeMap & 8192 ? 32 : 0));}
|
||||
inline uint8_t rotation() { return ((typeMap & 16384 ? 1 : 0) + (typeMap & 32768 ? 2 : 0)); }
|
||||
inline uint8_t slopeType() { return ((typeMap & 256 ? 1 : 0) +
|
||||
(typeMap & 512 ? 2 : 0) + (typeMap & 1024 ? 4 : 0) +
|
||||
(typeMap & 2048 ? 8 : 0) + (typeMap & 4096 ? 16 : 0) +
|
||||
(typeMap & 8192 ? 32 : 0)); }
|
||||
inline uint8_t rotation() { return ((typeMap & 16384 ? 1 : 0) +
|
||||
(typeMap & 32768 ? 2 : 0)); }
|
||||
/* m1win seems to indicate:
|
||||
* 000 - Nothing
|
||||
* 001 - traffic lights
|
||||
@ -414,6 +419,16 @@ namespace OpenGTA {
|
||||
* 110 - railway station
|
||||
* 111 - railway station train
|
||||
*/
|
||||
|
||||
inline void setUpOk(bool v) { if (v) typeMap |= 1; else typeMap &= ~1; }
|
||||
inline void setDownOk(bool v) { if (v) typeMap |= 2; else typeMap &= ~2; }
|
||||
inline void setLeftOk(bool v) { if (v) typeMap |= 4; else typeMap &= ~4; }
|
||||
inline void setRightOk(bool v) { if (v) typeMap |= 8; else typeMap &= ~8; }
|
||||
inline void setIsFlat(bool v) { if (v) typeMap |= 128; else typeMap &= ~128; }
|
||||
void setBlockType(uint8_t v);
|
||||
void setSlopeType(uint8_t v);
|
||||
void setRotation(uint8_t v);
|
||||
|
||||
inline bool trafficLights() { return (typeMapExt & 1); }
|
||||
inline bool railEndTurn() { return (typeMapExt & 4); }
|
||||
inline bool railStartTurn() { return ((typeMapExt & 4) && (typeMapExt &1)); }
|
||||
@ -450,6 +465,8 @@ namespace OpenGTA {
|
||||
NavData *nav;
|
||||
ObjectPosition *objects;
|
||||
PHYSFS_uint16 numObjects;
|
||||
const Location & getNearestLocationByType(uint8_t t, uint8_t x, uint8_t y);
|
||||
const LocationMap & getLocationMap() { return locations; }
|
||||
protected:
|
||||
|
||||
PHYSFS_uint32 base[GTA_MAP_MAXDIMENSION][GTA_MAP_MAXDIMENSION];
|
||||
|
@ -13,7 +13,7 @@ function program_exists() {
|
||||
function print_make_file_list() {
|
||||
FOO=GL_SRC
|
||||
FOOO=GL_OBJ
|
||||
( grep -l "^namespace OpenGL" *.cpp ;echo "gl_frustum.cpp";echo "math/obox.cpp coldet/math3d.cpp util/physfsrwops.c" ) | sort | xargs echo "$FOO ="
|
||||
( grep -l "^namespace OpenGL" *.cpp ;echo "gl_frustum.cpp";echo "math/obox.cpp math/plane.cpp coldet/math3d.cpp util/physfsrwops.c" ) | sort | xargs echo "$FOO ="
|
||||
echo "$FOOO = \${$FOO:.cpp=.o}"
|
||||
FOO=OGTA_SRC
|
||||
FOOO=OGTA_OBJ
|
||||
@ -71,9 +71,9 @@ viewer${EXE_PFIX}: main2.cpp viewer.o \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) \$(OS
|
||||
-o \$@ \$+ \\
|
||||
\$(SDL_LIB) \$(SDL_GL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(COLDET_LIB)
|
||||
|
||||
luaviewer${EXE_PFIX}: main2.cpp viewer.cpp \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) \$(OSTEER_OBJ) \
|
||||
luaviewer${EXE_PFIX}: main2.cpp viewer.o \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) \$(OSTEER_OBJ) \
|
||||
\$(LUA_OBJ)
|
||||
\$(CXX) \$(CATCH_E) -DWITH_LUA \$(FLAGS) \$(DEFS) \\
|
||||
\$(CXX) \$(CATCH_E) \$(FLAGS) \$(DEFS) \\
|
||||
\$(INC) \\
|
||||
-o \$@ \$+ \\
|
||||
\$(SDL_LIB) \$(SDL_GL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(COLDET_LIB) \$(LUA_LIB)
|
||||
@ -89,6 +89,11 @@ slopeview: main.o tools/display_slopes.o navdata.o read_cmp.o \
|
||||
\$(UTIL_OBJ) common_sdl_gl.o
|
||||
\$(CXX) \$(CXXFLAGS) -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB) -lSDL_image
|
||||
|
||||
blockview: main2.o tools/blockview.cpp util/log.o util/m_exceptions.o \
|
||||
gl_camera.o gl_screen.o read_cmp.o dataholder.o slope_height_func.o navdata.o \
|
||||
datahelper.o read_gry.o read_g24.o util/set.o util/buffercache.o read_fxt.o blockdata.o
|
||||
\$(CXX) \$(CXXFLAGS) -o \$@ \$+ \$(SDL_LIB) \$(SDL_GL_LIB) \$(PHYSFS_LIB)
|
||||
|
||||
g24: read_g24.cpp read_gry.o \$(UTIL_OBJ)
|
||||
\$(CXX) -DG24_DUMPER \$(CXXFLAGS) -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB)
|
||||
|
||||
@ -305,6 +310,8 @@ OPT = $OPT
|
||||
WARN = $WARN
|
||||
DEFS = $DEFS
|
||||
|
||||
LIB_RT_PATH = libs
|
||||
|
||||
# def only for 'main' programs to let gdb handle the exception
|
||||
#CATCH_E = -DDONT_CATCH
|
||||
|
||||
@ -312,7 +319,7 @@ DEFS = $DEFS
|
||||
|
||||
# the external libraries
|
||||
PHYSFS_INC = -Iinc
|
||||
PHYSFS_LIB = -Llibs -lphysfs -lz
|
||||
PHYSFS_LIB = -Llibs -lphysfs-1-1-0 -lzlib1
|
||||
|
||||
SDL_INC = -Iinc -D_GNU_SOURCE=1 -D_REENTRANT
|
||||
SDL_LIB = -Llibs -lSDLmain -lSDL
|
||||
@ -379,17 +386,28 @@ function print_config_h() {
|
||||
#define DEFAULT_SCREEN_WIDTH 640
|
||||
#define DEFAULT_SCREEN_HEIGHT 480
|
||||
|
||||
// 0 - no vsync (default), 1 - try to use SDL_GL_SWAP_CONTROL,
|
||||
// 2 - try native call (GLX on linux, unsupported on win32)
|
||||
//#undef DEFAULT_SCREEN_VSYNC
|
||||
#define DEFAULT_SCREEN_VSYNC 2
|
||||
|
||||
// default pathes; env-variables can override
|
||||
#define OGTA_DEFAULT_DATA_PATH "gtadata.zip"
|
||||
#define OGTA_DEFAULT_MOD_PATH ""
|
||||
#define OGTA_DEFAULT_HOME_PATH PHYSFS_getBaseDir()
|
||||
|
||||
// just for fun
|
||||
#define USED_GCC_VERSION "$GCC_VERSION"
|
||||
|
||||
// enable features
|
||||
#define DO_SCALEX
|
||||
#undef WITH_LUA
|
||||
#define DO_SCALE2X
|
||||
$SDL_SOUND_MIXER
|
||||
$SDL_GL_SWAP_CONTROL
|
||||
|
||||
// use escape sequences to mark Log::info/warn/error()
|
||||
#ifdef LINUX
|
||||
//#define LOG_USE_ANSI_COLORS
|
||||
#endif
|
||||
EOF
|
||||
}
|
||||
|
||||
@ -401,6 +419,7 @@ if [[ -n "$1" && "$1" != "LINUX" ]]; then
|
||||
print_w32settings > src_list.make
|
||||
print_make_file_list >> src_list.make
|
||||
print_target_list >> src_list.make
|
||||
SDL_GL_SWAP_CONTROL='#define HAVE_SDL_VSYNC'
|
||||
else
|
||||
OGTA_PLATFORM="LINUX"
|
||||
echo "*** LINUX ***"
|
||||
|
91
read_cmp.cpp
91
read_cmp.cpp
@ -22,6 +22,70 @@
|
||||
*/
|
||||
namespace OpenGTA {
|
||||
|
||||
void Map::BlockInfo::setBlockType(uint8_t v) {
|
||||
switch(v) {
|
||||
case 0:
|
||||
typeMap &= ~(16 | 32 | 64);
|
||||
break;
|
||||
case 1:
|
||||
typeMap |= 16;
|
||||
typeMap &= ~(32 | 64);
|
||||
break;
|
||||
case 2:
|
||||
typeMap |= 32;
|
||||
typeMap &= ~(16 | 64);
|
||||
break;
|
||||
case 3:
|
||||
typeMap |= (16 | 32);
|
||||
typeMap &= ~64;
|
||||
break;
|
||||
case 4:
|
||||
typeMap |= 64;
|
||||
typeMap &= ~(16 | 32);
|
||||
break;
|
||||
case 5:
|
||||
typeMap |= (16 | 64);
|
||||
typeMap &= ~32;
|
||||
break;
|
||||
case 6:
|
||||
typeMap |= (32 | 64);
|
||||
typeMap &= ~16;
|
||||
break;
|
||||
case 7:
|
||||
typeMap |= (16 | 32 | 64);
|
||||
break;
|
||||
default:
|
||||
ERROR << "Invalid block-type: " << int(v) << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::BlockInfo::setSlopeType(uint8_t v) {
|
||||
WARN << "NOT IMPLEMENTED" << std::endl;
|
||||
}
|
||||
|
||||
void Map::BlockInfo::setRotation(uint8_t v) {
|
||||
switch(v) {
|
||||
case 0:
|
||||
typeMap &= ~(16384 | 32768);
|
||||
break;
|
||||
case 1:
|
||||
typeMap |= 16384;
|
||||
typeMap &= ~32768;
|
||||
break;
|
||||
case 2:
|
||||
typeMap |= 32768;
|
||||
typeMap &= ~16384;
|
||||
break;
|
||||
case 3:
|
||||
typeMap |= (16384 | 32768);
|
||||
break;
|
||||
default:
|
||||
ERROR << "Invalid rotation: " << int(v) << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Map::Map(const std::string& filename) {
|
||||
nav = 0;
|
||||
fd = PHYSFS_openRead(filename.c_str());
|
||||
@ -204,6 +268,7 @@ namespace OpenGTA {
|
||||
PHYSFS_read(fd, static_cast<void*>(&loc.x), 1, 1);
|
||||
PHYSFS_read(fd, static_cast<void*>(&loc.y), 1, 1);
|
||||
PHYSFS_read(fd, static_cast<void*>(&loc.z), 1, 1);
|
||||
// skip dummy entries at 0,0,0
|
||||
if ((loc.x == 0) && (loc.y == 0) && (loc.z == 0))
|
||||
continue;
|
||||
if (i < 6)
|
||||
@ -266,6 +331,32 @@ namespace OpenGTA {
|
||||
}
|
||||
}
|
||||
}
|
||||
const Map::Location & Map::getNearestLocationByType(uint8_t t, uint8_t x, uint8_t y) {
|
||||
INFO << int(t) << " at " << int(x) << " " << int(y) << std::endl;
|
||||
LocationMap::iterator i = locations.find(t);
|
||||
LocationMap::iterator j;
|
||||
if (i == locations.end()) {
|
||||
std::ostringstream o;
|
||||
o << "location-type " << int(t) << " not found in map";
|
||||
throw E_UNKNOWNKEY(o.str());
|
||||
}
|
||||
int _x(x);
|
||||
int _y(y);
|
||||
int min_d = 255 * 255;
|
||||
#define ABS(a) (a > 0 ? a : -a)
|
||||
|
||||
while (i != locations.end()) {
|
||||
INFO << int(i->first) << ": "<< int(i->second->x) << " " << int(i->second->y) << std::endl;
|
||||
int d = ABS((_x - i->second->x)) + ABS((_y - i->second->y));
|
||||
if (d < min_d) {
|
||||
min_d = d;
|
||||
j = i;
|
||||
}
|
||||
}
|
||||
#undef ABS
|
||||
return *j->second;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
13
read_fxt.cpp
13
read_fxt.cpp
@ -77,6 +77,9 @@ namespace OpenGTA {
|
||||
//std::cout << tmp << " : " << buff << std::endl;
|
||||
/*else
|
||||
std::cout << "Skipping: " << tmp << ": " << buff << std::endl;*/
|
||||
#ifdef FXT_TEST
|
||||
std::cout << tmp << " : " << buff << std::endl;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
buff[i] = v;
|
||||
@ -122,11 +125,19 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
#if FXT_TEST
|
||||
#include "file_helper.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
PHYSFS_init(argv[0]);
|
||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||
OpenGTA::MessageDB* strings = new OpenGTA::MessageDB();
|
||||
const char* lang = getenv("OGTA_LANG");
|
||||
if (!lang)
|
||||
lang = getenv("LANG");
|
||||
if (!lang)
|
||||
lang = "en";
|
||||
OpenGTA::MessageDB* strings = new OpenGTA::MessageDB(
|
||||
Util::FileHelper::lang2MsgFilename(lang)
|
||||
);
|
||||
std::cout << strings->getText(1001) << std::endl;
|
||||
|
||||
delete strings;
|
||||
|
36
read_gry.cpp
36
read_gry.cpp
@ -279,6 +279,15 @@ namespace OpenGTA {
|
||||
return _type;
|
||||
}
|
||||
|
||||
uint8_t GraphicsBase::getFormat() {
|
||||
if (_topHeaderSize == 52)
|
||||
return 0;
|
||||
else if (_topHeaderSize == 64)
|
||||
return 1;
|
||||
throw E_INVALIDFORMAT("graphics-base header size");
|
||||
return 255;
|
||||
}
|
||||
|
||||
Graphics8Bit::Graphics8Bit(const std::string& style) : GraphicsBase() {
|
||||
fd = PHYSFS_openRead(style.c_str());
|
||||
if (fd == NULL) {
|
||||
@ -344,8 +353,6 @@ namespace OpenGTA {
|
||||
"#object-info: " << objectInfos.size() << " #car-info: " << carInfos.size() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Graphics8Bit::loadHeader() {
|
||||
PHYSFS_uint32 vc;
|
||||
PHYSFS_readULE32(fd, &vc);
|
||||
@ -600,8 +607,8 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
for (int i=0; i < car->numDoors; i++) {
|
||||
PHYSFS_readSLE16(fd, &car->door[i].rpx);
|
||||
PHYSFS_readSLE16(fd, &car->door[i].rpy);
|
||||
PHYSFS_readSLE16(fd, &car->door[i].rpx);
|
||||
PHYSFS_readSLE16(fd, &car->door[i].object);
|
||||
PHYSFS_readSLE16(fd, &car->door[i].delta);
|
||||
bytes_read += 4 * 2;
|
||||
@ -777,14 +784,26 @@ namespace OpenGTA {
|
||||
const unsigned int b_offset = 256 * info.yoffset + info.xoffset;
|
||||
if (delta_is_a_set) {
|
||||
Util::Set delta_set(32, (unsigned char*)&delta);
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
if (delta_set.get_item(i)) {
|
||||
assert(i < info.deltaCount);
|
||||
const DeltaInfo & di = info.delta[i];
|
||||
applyDelta(info, buffer, b_offset, di);
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
for (int i=20; i < 24; i++) {
|
||||
if (delta_set.get_item(i)) {
|
||||
const DeltaInfo & di = info.delta[i - 20 + 6];
|
||||
applyDelta(info, buffer, b_offset, di, true);
|
||||
}
|
||||
}
|
||||
for (int i=24; i < 28; i++) {
|
||||
if (delta_set.get_item(i)) {
|
||||
const DeltaInfo & di = info.delta[i - 24 + 11];
|
||||
applyDelta(info, buffer, b_offset, di, true);
|
||||
}
|
||||
}
|
||||
//assert(0);
|
||||
}
|
||||
else {
|
||||
// delta is only an index; one to big
|
||||
@ -1006,6 +1025,13 @@ namespace OpenGTA {
|
||||
|
||||
int Graphics8Bit::RGBPalette::loadFromFile(PHYSFS_file* fd) {
|
||||
PHYSFS_read(fd, static_cast<void*>(&data), 1, 256*3);
|
||||
/*
|
||||
int max_sum = 0;
|
||||
for (int i = 1; i < 256; i+=3) {
|
||||
int sum = int(data[i]) + int(data[i+1]) + int(data[i+2]);
|
||||
if (sum > max_sum)
|
||||
max_sum = sum;
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#include <sstream>
|
||||
#include <cassert>
|
||||
#include "m_exceptions.h"
|
||||
#include "fx_sdt.h"
|
||||
|
||||
|
55
readme.txt
55
readme.txt
@ -15,6 +15,14 @@
|
||||
* GNU Make
|
||||
[ http://www.gnu.org/software/make/ ]
|
||||
|
||||
= Optional software =
|
||||
* Lua
|
||||
[ http://www.lua.org/ ]
|
||||
* SDL_mixer
|
||||
[ http://www.libsdl.org/projects/SDL_mixer/ ]
|
||||
* SDL_sound
|
||||
[ http://icculus.org/SDL_sound/ ]
|
||||
|
||||
= Compiling =
|
||||
|
||||
Only tested on GNU Linux using gcc & make; I assume that GL, SDL and
|
||||
@ -27,7 +35,7 @@ The other programs are/were used for development or debugging.
|
||||
The distributed win32 binaries are created with a cross-compiler.
|
||||
|
||||
The file doc/compiling.txt in the source code release contains
|
||||
information on the build process.
|
||||
more information about the build process.
|
||||
|
||||
= Installing the data-files =
|
||||
|
||||
@ -37,7 +45,7 @@ These programs expect to find the data in the current directory, either
|
||||
directly in the file-system or in a ZIP file (named 'gtadata.zip').
|
||||
You want the content of the original game directory GTADATA, but not
|
||||
the directory itself.
|
||||
See mods/using_mods.txt for a slightly longer description.
|
||||
See doc/using_mods.txt for a slightly longer description.
|
||||
|
||||
Needed:
|
||||
*.FXT, *.FON, *.CMP
|
||||
@ -52,13 +60,28 @@ MISSION.INI
|
||||
AUDIO/*.RAW AUDIO/*.SDT (sound effects)
|
||||
AUDIO/*.WAV (cutscene text; in legacy format)
|
||||
|
||||
You may also want to keep the music (even though it isn't used yet).
|
||||
It is safe to assume that Ogg Vorbis [ http://vorbis.com/ ] will
|
||||
be supported, so you can encode the music files.
|
||||
|
||||
= Running =
|
||||
|
||||
Note: Binary releases only contain the 'viewer' application; the other
|
||||
programs should only be intersting for developers (read: compile
|
||||
them yourself).
|
||||
|
||||
== gfxextract ==
|
||||
|
||||
Export/Display textures and sprites;
|
||||
run ./gfxextract -h (or without any parameters) for usage info.
|
||||
|
||||
== spriteplayer ==
|
||||
|
||||
Sprite graphics browser; shows internal indices, can display
|
||||
animations (ped walking, car delta anims).
|
||||
|
||||
run ./spriteplayer -h for usage information.
|
||||
|
||||
== viewer ==
|
||||
|
||||
Brain-dead immediate-mode renderer of the city (now with objects); with
|
||||
@ -72,33 +95,14 @@ The optional param loads the respective city; default is 0:
|
||||
1 - SANB.CMP
|
||||
2 - MIAMI.CMP
|
||||
|
||||
flags are:
|
||||
There are several flags; see the compiled-in usage information.
|
||||
|
||||
-V show version and compile time switches
|
||||
-h show usage
|
||||
|
||||
( The compiled-in usage information is more recent than the
|
||||
following. )
|
||||
|
||||
* screen dimensions (have to specify neither or both)
|
||||
-w width
|
||||
-h height
|
||||
|
||||
* log verbosity
|
||||
-l level (0 default; everything, 1 warn + error, 2 only error)
|
||||
|
||||
Using "-l 1" will make it easier to see actual error messages;
|
||||
sometimes there is a lot of noise on 'info' level (0).
|
||||
|
||||
* style-file
|
||||
-c 0 (default; uses .GRY 8bit styles)
|
||||
-c 1 (uses .G24 24bit styles)
|
||||
|
||||
* other map & graphics files (have to specify neither or both)
|
||||
-m map_filename -g style_filename
|
||||
|
||||
This is for loading non-GTA1 data; like GTA London.
|
||||
|
||||
keys:
|
||||
|
||||
ESC, cursor-keys, + and - do what you might except them to do;
|
||||
@ -108,7 +112,7 @@ furthermore:
|
||||
. : decrease visible range
|
||||
, : increase visible range
|
||||
t : display entire city (at a crawl)
|
||||
f : toggle fullscreen/windowed
|
||||
f : toggle fullscreen/windowed [only works on Linux]
|
||||
PRINT : save 'screenshot.bmp' in current directory
|
||||
p : dump coords (in lua syntax) to stdout
|
||||
F2 : toggle drawing of sprite bounding-boxes
|
||||
@ -118,6 +122,7 @@ furthermore:
|
||||
F6 : city map mode (ESC to exit, +, -, cursor keys)
|
||||
F9 : toggle city blocks drawn textured
|
||||
F10 : toggle blocks wireframe lines
|
||||
F12 : show/hide screen-gamma scrollbar
|
||||
|
||||
in 3d view:
|
||||
w : forward
|
||||
@ -132,11 +137,15 @@ to 3d and the screen is black: move the mouse down.
|
||||
in follow-player mode:
|
||||
i,j,k,l : move player-char
|
||||
l-shift : toggle walking/running
|
||||
l-ctrl : shoot
|
||||
0 : unselect weapon / unarmed
|
||||
1,2,3,4 : select weapon (only switches graphic)
|
||||
F7 : draw explosion at player pos (graphical effect)
|
||||
F8 : create random-walker ped at player-pos
|
||||
|
||||
You can still use + and - to zoom; but the view will try
|
||||
to return to the old position quickly.
|
||||
|
||||
== luaviewer: viewer + Lua (optional target) ==
|
||||
|
||||
Also needs Lua (only 5.1 tried) in path; run: 'make luaviewer'
|
||||
|
@ -1,3 +1,5 @@
|
||||
ogta/ai.cpp
|
||||
ogta/ai.h
|
||||
ogta/blockanim.cpp
|
||||
ogta/blockanim.h
|
||||
ogta/blockdata.cpp
|
||||
@ -24,17 +26,22 @@ ogta/coldet/transform.txt
|
||||
ogta/coldet/tritri.c
|
||||
ogta/common_sdl_gl.cpp
|
||||
ogta/common_sdl_gl.h
|
||||
ogta/cvs_changelog.txt
|
||||
ogta/datahelper.cpp
|
||||
ogta/datahelper.h
|
||||
ogta/dataholder.cpp
|
||||
ogta/dataholder.h
|
||||
ogta/doc/compiling.txt
|
||||
ogta/doc/doc_links.txt
|
||||
ogta/doc/gouranga.txt
|
||||
ogta/doc/gta1_winex.txt
|
||||
ogta/doc/hacking.txt
|
||||
ogta/doc/more_hints_delfi.txt
|
||||
ogta/doc/more_info.txt
|
||||
ogta/doc/ped_remaps.txt
|
||||
ogta/doc/slopes1.txt
|
||||
ogta/doc/sprites.txt
|
||||
ogta/doc/using_mods.txt
|
||||
ogta/Doxyfile
|
||||
ogta/entity_controller.cpp
|
||||
ogta/entity_controller.h
|
||||
@ -70,6 +77,7 @@ ogta/licenses/readme.txt
|
||||
ogta/licenses/zlib.txt
|
||||
ogta/license.txt
|
||||
ogta/lid_normal_data.h
|
||||
ogta/localplayer.cpp
|
||||
ogta/localplayer.h
|
||||
ogta/loki.make
|
||||
ogta/loki.make.w32_cross
|
||||
@ -80,6 +88,8 @@ ogta/lua_addon/lua_cityview.h
|
||||
ogta/lua_addon/lua.hpp
|
||||
ogta/lua_addon/lua_ini_bridge.cpp
|
||||
ogta/lua_addon/lua_ini_bridge.h
|
||||
ogta/lua_addon/lua_map.cpp
|
||||
ogta/lua_addon/lua_map.h
|
||||
ogta/lua_addon/lua_screen.cpp
|
||||
ogta/lua_addon/lua_screen.h
|
||||
ogta/lua_addon/lua_spritecache.cpp
|
||||
@ -101,6 +111,8 @@ ogta/math/obb.cpp
|
||||
ogta/math/obb.hpp
|
||||
ogta/math/obox.cpp
|
||||
ogta/math/obox.h
|
||||
ogta/math/plane.cpp
|
||||
ogta/math/plane.h
|
||||
ogta/math/quaternion.h
|
||||
ogta/math/rectangle.hpp
|
||||
ogta/math/vector.hpp
|
||||
@ -136,6 +148,9 @@ ogta/release_files_sorted
|
||||
ogta/scripts/demo1.lua
|
||||
ogta/scripts/demo2.lua
|
||||
ogta/scripts/demo3.lua
|
||||
ogta/scripts/dump_config.lua
|
||||
ogta/scripts/map_test_blocktype.lua
|
||||
ogta/scripts/parser.lua
|
||||
ogta/slope1_data.h
|
||||
ogta/slope1_tcoords.h
|
||||
ogta/slope_height_func.cpp
|
||||
@ -143,25 +158,39 @@ ogta/sprite_anim_player.cpp
|
||||
ogta/spritemanager.cpp
|
||||
ogta/spritemanager.h
|
||||
ogta/tests/interpolate_test.cpp
|
||||
ogta/tests/lua_map_test.cpp
|
||||
ogta/tests/menudemo.cpp
|
||||
ogta/tests/new_obj_test.cpp
|
||||
ogta/tests/plot_interpolate.sh
|
||||
ogta/tests/rectangle.cpp
|
||||
ogta/tests/sound_test1.cpp
|
||||
ogta/tools/analyse_lids_2.c
|
||||
ogta/tools/analyse_lids.c
|
||||
ogta/tools/blockview.cpp
|
||||
ogta/tools/bug_parser.awk
|
||||
ogta/tools/build_svg_rect.sh
|
||||
ogta/tools/car_dump.cpp
|
||||
ogta/tools/create_normals.cpp
|
||||
ogta/tools/display_font.cpp
|
||||
ogta/tools/display_slopes.cpp
|
||||
ogta/tools/doxy_doc.sh
|
||||
ogta/tools/fxt.c
|
||||
ogta/tools/gen_texcoords.c
|
||||
ogta/tools/insert_copyright.sh
|
||||
ogta/tools/label_screenshot.sh
|
||||
ogta/tools/mapinfo.cpp
|
||||
ogta/tools/minimap.cpp
|
||||
ogta/tools/obj_dump.cpp
|
||||
ogta/tools/package_binary.sh
|
||||
ogta/tools/picasa_ls.sh
|
||||
ogta/tools/plot_stats.sh
|
||||
ogta/tools/projects_stats.sh
|
||||
ogta/tools/raw_images.m4
|
||||
ogta/tools/replace_in_files.sh
|
||||
ogta/tools/resort_quads.c
|
||||
ogta/tools/slope_conv.awk
|
||||
ogta/tools/slope_exchange.sh
|
||||
ogta/tools/stats_recalc.sh
|
||||
ogta/tools/style_demo.sh
|
||||
ogta/train_system.cpp
|
||||
ogta/train_system.h
|
||||
@ -175,15 +204,20 @@ ogta/util/cell_iterator.h
|
||||
ogta/util/cistring.h
|
||||
ogta/util/file_helper.cpp
|
||||
ogta/util/file_helper.h
|
||||
ogta/util/gui.cpp
|
||||
ogta/util/gui.h
|
||||
ogta/util/image_loader.cpp
|
||||
ogta/util/image_loader.h
|
||||
ogta/util/key_handler.cpp
|
||||
ogta/util/key_handler.h
|
||||
ogta/util/log.cpp
|
||||
ogta/util/log.h
|
||||
ogta/util/map_helper.cpp
|
||||
ogta/util/map_helper.h
|
||||
ogta/util/m_exceptions.cpp
|
||||
ogta/util/m_exceptions.h
|
||||
ogta/util/pf_tree.cpp
|
||||
ogta/util/pf_tree.hpp
|
||||
ogta/util/physfsrwops.c
|
||||
ogta/util/physfsrwops.h
|
||||
ogta/util/sample_cache.h
|
||||
|
@ -20,7 +20,7 @@ tick = 0
|
||||
-- every 100 ms, but it is pretty pointless at this time.
|
||||
function game_tick()
|
||||
if tick == 1 then
|
||||
screen.makeScreenShot("test.bmp")
|
||||
--screen.makeScreenShot("test.bmp")
|
||||
end
|
||||
tick = tick + 1
|
||||
end
|
||||
|
@ -1,4 +1,5 @@
|
||||
screen.setFullscreen(true)
|
||||
|
||||
--screen.setFullscreen(true)
|
||||
camera.setCenter(61.4261, 7.56265, 2.2242)
|
||||
camera.setEye(61.4185, 8.72266, 0.810034)
|
||||
camera.setUp(0, 1, 0)
|
||||
|
40
scripts/dump_config.lua
Normal file
40
scripts/dump_config.lua
Normal file
@ -0,0 +1,40 @@
|
||||
function pairsByKeys (t, f)
|
||||
local a = {}
|
||||
for n in pairs(t) do table.insert(a, n) end
|
||||
table.sort(a, f)
|
||||
local i = 0 -- iterator variable
|
||||
local iter = function () -- iterator function
|
||||
i = i + 1
|
||||
if a[i] == nil then return nil
|
||||
else return a[i], t[a[i]]
|
||||
end
|
||||
end
|
||||
return iter
|
||||
end
|
||||
|
||||
function config_as_string()
|
||||
local conf_str = ""
|
||||
if type(config) ~= 'table' then return conf_str end
|
||||
table.sort(config)
|
||||
for i, j in pairsByKeys(config) do
|
||||
if type(j) == 'boolean' then
|
||||
if j == true then
|
||||
conf_str = conf_str .. i .. ' = true\n'
|
||||
else
|
||||
conf_str = conf_str .. i .. ' = false\n'
|
||||
end
|
||||
elseif type(j) == 'string' then
|
||||
conf_str = conf_str .. i .. ' = "' .. j .. '"\n'
|
||||
else
|
||||
conf_str = conf_str .. i .. ' = ' .. j .. '\n'
|
||||
end
|
||||
end
|
||||
return conf_str
|
||||
end
|
||||
|
||||
|
||||
print("-- CONFIG DUMP --")
|
||||
print(config_as_string())
|
||||
print("-- END OF CONFIG --")
|
||||
quit()
|
||||
|
97
scripts/map_test_blocktype.lua
Normal file
97
scripts/map_test_blocktype.lua
Normal file
@ -0,0 +1,97 @@
|
||||
-- run it:
|
||||
-- ./lua_map_test $map_file scripts/map_test_blocktype.lua
|
||||
--
|
||||
-- may soon also work from within luaviewer
|
||||
|
||||
if rawget(_G, 'map') == nil then
|
||||
print("No map loaded!")
|
||||
os.exit()
|
||||
end
|
||||
|
||||
function block_type_name(t)
|
||||
if t == 0 then return "air" end
|
||||
if t == 1 then return "water" end
|
||||
if t == 2 then return "road" end
|
||||
if t == 3 then return "pavement" end
|
||||
if t == 4 then return "field" end
|
||||
if t == 5 then return "building" end
|
||||
if t == 6 then return "unused1" end
|
||||
if t == 7 then return "unused2" end
|
||||
return "????????"
|
||||
end
|
||||
|
||||
function find_all_of_type(t)
|
||||
list = {}
|
||||
for y = 0, 255 do
|
||||
for x = 0, 255 do
|
||||
c = map:getNumBlocksAt(x, y)
|
||||
for i = 0, c - 1 do
|
||||
info = map:getBlockAt(x, y, i)
|
||||
if info:getBlockType() == t then
|
||||
table.insert(list, { x, y, i })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
|
||||
function find_air_columns()
|
||||
for y = 0, 255 do
|
||||
for x = 0, 255 do
|
||||
c = map:getNumBlocksAt(x, y)
|
||||
is_air = true
|
||||
for i = 0, c - 1 do
|
||||
info = map:getBlockAt(x, y, i)
|
||||
if info:getBlockType() ~= 0 then
|
||||
is_air = false
|
||||
end
|
||||
end
|
||||
if is_air == true then
|
||||
for i = 0, c - 1 do
|
||||
info = map:getBlockAt(x, y, i)
|
||||
lid = info:getTextureId(0)
|
||||
if lid > 0 and i < 4 then
|
||||
print("Air-column: " .. x .. ", " .. y)
|
||||
print("Texture " .. lid .. " set at " .. i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function is_block_of_type(x, y, z, t)
|
||||
local c = map:getNumBlocksAt(x, y)
|
||||
assert(c > z)
|
||||
local info = map:getBlockAt(x, y, z)
|
||||
return info:getBlockType() == t
|
||||
end
|
||||
|
||||
--find_air_columns()
|
||||
|
||||
function find_block_holes()
|
||||
for y = 0, 255 do
|
||||
for x = 0, 255 do
|
||||
c = map:getNumBlocksAt(x, y)
|
||||
info = map:getBlockAt(x, y, c - 1)
|
||||
if info:getTextureId(0) > 0 and info:getBlockType() == 0 then
|
||||
print(x .. ", " .. y .. " has texture but no type above; level: " .. c - 1 ..
|
||||
" lid: " .. info:getTextureId(0))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
find_block_holes()
|
||||
|
||||
--num = map:getNumBlocksAt(25, 17)
|
||||
--for i = 0, num-1 do
|
||||
-- info = map:getBlockAt(25, 17, i)
|
||||
-- info:setBlockType(3)
|
||||
-- print(i)
|
||||
-- print("texture: " .. info:getTextureId(0))
|
||||
-- print("type: " .. info:getBlockType())
|
||||
--end
|
122
scripts/parser.lua
Normal file
122
scripts/parser.lua
Normal file
@ -0,0 +1,122 @@
|
||||
local n
|
||||
--definition_indices = {}
|
||||
--for n in pairs(definitions) do table.insert(definition_indices, n) end
|
||||
--table.sort(definition_indices)
|
||||
|
||||
command_indices = {}
|
||||
for n in pairs(commands) do table.insert(command_indices, n) end
|
||||
table.sort(command_indices)
|
||||
|
||||
function idx_by_gtaidx(gta_idx)
|
||||
local i
|
||||
for i = 1, #command_indices do
|
||||
if command_indices[i] == gta_idx then return i end
|
||||
end
|
||||
--error("Invalid gta-cmd-idx: " .. gta_idx)
|
||||
return -1
|
||||
end
|
||||
|
||||
-- from: http://lua-users.org/wiki/StringRecipes
|
||||
-- Compatibility: Lua-5.1
|
||||
function split(str, pat)
|
||||
local t = {} -- NOTE: use {n = 0} in Lua-5.0
|
||||
local fpat = "(.-)" .. pat
|
||||
local last_end = 1
|
||||
local s, e, cap = string.find(str, fpat, 1)
|
||||
while s do
|
||||
if s ~= 1 or cap ~= "" then
|
||||
table.insert(t,cap)
|
||||
end
|
||||
last_end = e+1
|
||||
s, e, cap = string.find(str, fpat, last_end)
|
||||
end
|
||||
if last_end <= string.len(str) then
|
||||
cap = string.sub(str, last_end)
|
||||
table.insert(t, cap)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
function run_command(idx, cmd, params)
|
||||
local res = 0
|
||||
if cmd == "KICKSTART" then
|
||||
-- new_thread(idx, params[1])
|
||||
print("\tKICKSTART in " .. idx .. " from " .. params[1] .. " = " ..idx_by_gtaidx(params[1] + 0))
|
||||
new_thread(idx, idx_by_gtaidx(params[1] + 0))
|
||||
else
|
||||
print("\t" .. cmd .. " in line " .. idx)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function iterate_commands(idx)
|
||||
local is_sleeping = false
|
||||
while idx <= #command_indices do
|
||||
local gta_idx = command_indices[idx]
|
||||
if is_sleeping == true then
|
||||
while true do
|
||||
print(" thread is sleeping in " .. gta_idx)
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
--print("LINE " .. gta_idx)
|
||||
local cmd = commands[gta_idx]
|
||||
local cmd_split = split(cmd, " ")
|
||||
local cmd_name = cmd_split[1]
|
||||
--print(cmd)
|
||||
table.remove(cmd_split, 1)
|
||||
local ok_idx = cmd_split[2]
|
||||
local fail_idx = cmd_split[3]
|
||||
if idx == 1 then
|
||||
idx = idx + 1
|
||||
elseif idx > 1 then
|
||||
local next_idx = 0
|
||||
--print(" "..gta_idx .. " " .. cmd_name)
|
||||
if run_command(gta_idx, cmd_name, cmd_split) == 1 then
|
||||
next_idx = fail_idx + 0
|
||||
print(' failed '..fail_idx)
|
||||
else
|
||||
next_idx = ok_idx + 0
|
||||
print(' ok '..ok_idx)
|
||||
end
|
||||
if next_idx == 0 then
|
||||
idx = idx + 1
|
||||
elseif next_idx == -1 then
|
||||
if cmd_name == "CRANE" then idx = idx + 1
|
||||
else
|
||||
is_sleeping = true
|
||||
--error("EXIT: " .. next_idx)
|
||||
end
|
||||
else
|
||||
idx = idx_by_gtaidx(next_idx)
|
||||
end
|
||||
end
|
||||
coroutine.yield()
|
||||
print(' RESUMING2')
|
||||
end
|
||||
coroutine.yield()
|
||||
print(' RESUMING3')
|
||||
end
|
||||
|
||||
threads = {}
|
||||
thread_indices = {}
|
||||
function new_thread(t_id, start_at_idx)
|
||||
table.insert(threads, coroutine.create(function () iterate_commands(start_at_idx) end))
|
||||
print(" "..#threads .. " = " ..t_id)
|
||||
table.insert(thread_indices, t_id)
|
||||
end
|
||||
|
||||
|
||||
new_thread(0, 1)
|
||||
while #threads > 0 do
|
||||
for i, j in pairs(threads) do
|
||||
print("thread " .. thread_indices[i] .. " [" .. #threads .. "]")
|
||||
if coroutine.status(j) == "suspended" then
|
||||
coroutine.resume(j)
|
||||
elseif coroutine.status(j) == "dead" then
|
||||
table.remove(threads, i)
|
||||
table.remove(thread_indices, i)
|
||||
print("removing dead " .. i)
|
||||
end
|
||||
end
|
||||
end
|
@ -1084,11 +1084,12 @@
|
||||
{ 1.00, 1.00 }
|
||||
},
|
||||
{ // east
|
||||
{ 1.00, 0.00 },
|
||||
{ 0.00, 1.00 },
|
||||
{ 0.00, 1.00 },
|
||||
{ 1.00, 1.00 }
|
||||
{ 0.00, 0.00 },
|
||||
{ 1.00, 1.00 },
|
||||
{ 1.00, 1.00 },
|
||||
{ 0.00, 1.00 }
|
||||
}
|
||||
|
||||
},
|
||||
{ // slope: 42
|
||||
{ // north
|
||||
@ -1110,10 +1111,10 @@
|
||||
{ 1.00, 1.00 }
|
||||
},
|
||||
{ // east
|
||||
{ 1.00, 1.00 },
|
||||
{ 0.00, 0.00 },
|
||||
{ 0.00, 1.00 },
|
||||
{ 1.00, 1.00 }
|
||||
{ 1.00, 0.00 },
|
||||
{ 1.00, 1.00 },
|
||||
{ 0.00, 1.00 }
|
||||
}
|
||||
},
|
||||
{ // slope: 43
|
||||
|
@ -36,7 +36,10 @@
|
||||
extern int global_EC;
|
||||
extern int global_Done;
|
||||
std::string style_file("STYLE001.GRY");
|
||||
float screen_gamma = 1.0f;
|
||||
|
||||
OpenGTA::Car * car = NULL;
|
||||
Vector3D _p(4, 0.01f, 4);
|
||||
OpenGTA::Pedestrian ped(Vector3D(0.5f, 0.5f, 0.5f), Vector3D(4, 0.01f, 4), 0xffffffff);
|
||||
OpenGTA::SpriteObject::Animation pedAnim(0, 0);
|
||||
|
||||
@ -47,19 +50,43 @@ int first_offset = 0;
|
||||
int second_offset = 0;
|
||||
int now_frame = 0;
|
||||
bool play_anim = false;
|
||||
unsigned int play_anim_time = 0;
|
||||
int bbox_toggle = 0;
|
||||
int texsprite_toggle = 0;
|
||||
int c_c = 1;
|
||||
int car_model = 0;
|
||||
int car_remap = -1;
|
||||
int car_last_model_ok = 0;
|
||||
bool playWithCar = false;
|
||||
uint32_t car_delta = 0;
|
||||
|
||||
int spr_type = (int)ped.sprType;
|
||||
namespace OpenGTA {
|
||||
void ai_step_fake(OpenGTA::Pedestrian*) {
|
||||
}
|
||||
void ai_step_fake(OpenGTA::Pedestrian*) {
|
||||
}
|
||||
}
|
||||
|
||||
void on_exit() {
|
||||
void on_exit() {
|
||||
if (car)
|
||||
delete car;
|
||||
SDL_Quit();
|
||||
PHYSFS_deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void safe_try_model(uint8_t model_id) {
|
||||
if (car)
|
||||
delete car;
|
||||
car = NULL;
|
||||
try {
|
||||
car = new OpenGTA::Car(_p, 0, 0, model_id, car_remap);
|
||||
}
|
||||
catch (Util::UnknownKey & uk) {
|
||||
car = NULL;
|
||||
ERROR << "not a model" << std::endl;
|
||||
return;
|
||||
}
|
||||
car_last_model_ok = model_id;
|
||||
}
|
||||
|
||||
void run_init(const char*) {
|
||||
PHYSFS_init("mapview");
|
||||
@ -69,9 +96,14 @@ void run_init(const char*) {
|
||||
SDL_EnableKeyRepeat( 100, SDL_DEFAULT_REPEAT_INTERVAL );
|
||||
|
||||
OpenGTA::StyleHolder::Instance().load(style_file);
|
||||
OpenGTA::StyleHolder::Instance().get().setDeltaHandling(true);
|
||||
OpenGTA::MainMsgHolder::Instance().load("ENGLISH.FXT");
|
||||
|
||||
m_font.loadFont("STREET1.FON");
|
||||
m_font.setScale(2);
|
||||
m_font.loadFont("F_MTEXT.FON");
|
||||
m_font.setScale(1);
|
||||
glClearColor(1, 1, 1, 1);
|
||||
if (playWithCar)
|
||||
car = new OpenGTA::Car(_p, 0, 0, car_model);
|
||||
}
|
||||
|
||||
const char* spr_type_name(int t) {
|
||||
@ -122,6 +154,20 @@ const char* spr_type_name(int t) {
|
||||
return "???";
|
||||
}
|
||||
|
||||
const char* vtype2name(int vt) {
|
||||
switch(vt) {
|
||||
case 0:
|
||||
return "bus";
|
||||
case 3:
|
||||
return "motorcycle";
|
||||
case 4:
|
||||
return "car";
|
||||
case 8:
|
||||
return "train";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void drawScene(Uint32 ticks) {
|
||||
GL_CHECKERROR;
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@ -129,8 +175,36 @@ void drawScene(Uint32 ticks) {
|
||||
OpenGL::ScreenHolder::Instance().set3DProjection();
|
||||
OpenGL::CameraHolder::Instance().update(ticks);
|
||||
|
||||
if (play_anim) {
|
||||
pedAnim.firstFrameOffset = now_frame;
|
||||
if (playWithCar) {
|
||||
if (car) {
|
||||
car->update(ticks);
|
||||
OpenGTA::SpriteManagerHolder::Instance().draw(*car);
|
||||
}
|
||||
|
||||
OpenGL::ScreenHolder::Instance().setFlatProjection();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(10, 10, 0);
|
||||
std::ostringstream sprite_info_str;
|
||||
std::ostringstream ostr;
|
||||
ostr << "car" << int(car_model);
|
||||
|
||||
if (car) {
|
||||
sprite_info_str << vtype2name(car->carInfo.vtype)<< " model: " << int(car_model) << " name: " <<
|
||||
OpenGTA::MainMsgHolder::Instance().get().getText(ostr.str());
|
||||
}
|
||||
else
|
||||
sprite_info_str << "not a model: " << int(car_model);
|
||||
m_font.drawString(sprite_info_str.str());
|
||||
glPopMatrix();
|
||||
}
|
||||
else {
|
||||
if (play_anim && ticks > play_anim_time + 200) {
|
||||
now_frame++;
|
||||
if (now_frame > second_offset)
|
||||
now_frame = first_offset;
|
||||
ped.anim.firstFrameOffset = now_frame;
|
||||
play_anim_time = ticks;
|
||||
}
|
||||
OpenGTA::SpriteManagerHolder::Instance().draw(ped);
|
||||
|
||||
@ -142,6 +216,7 @@ void drawScene(Uint32 ticks) {
|
||||
sprite_info_str << spr_type_name(spr_type) << " offset " << frame_offset;
|
||||
m_font.drawString(sprite_info_str.str());
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
SDL_GL_SwapBuffers();
|
||||
GL_CHECKERROR;
|
||||
@ -155,25 +230,93 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
case SDLK_ESCAPE:
|
||||
global_Done = 1;
|
||||
break;
|
||||
case SDLK_TAB:
|
||||
c_c += 1; c_c %= 2;
|
||||
glClearColor(c_c, c_c, c_c, 0);
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
break;
|
||||
case 'k':
|
||||
if (car_delta > 0)
|
||||
car_delta -= 1;
|
||||
if (car)
|
||||
car->delta = car_delta;
|
||||
break;
|
||||
case 'l':
|
||||
if (car_delta < 32)
|
||||
car_delta += 1;
|
||||
if (car) {
|
||||
car->delta = car_delta;
|
||||
}
|
||||
break;
|
||||
case '+':
|
||||
cam.translateBy(Vector3D(0, -0.5f, 0));
|
||||
break;
|
||||
case '-':
|
||||
cam.translateBy(Vector3D(0, 0.5f, 0));
|
||||
break;
|
||||
case '1':
|
||||
if (playWithCar) {
|
||||
if (car->animState.get_item(1))
|
||||
car->closeDoor(0);
|
||||
else
|
||||
car->openDoor(0);
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
if (playWithCar) {
|
||||
if (car->animState.get_item(2))
|
||||
car->closeDoor(1);
|
||||
else
|
||||
car->openDoor(1);
|
||||
}
|
||||
break;
|
||||
case '3':
|
||||
if (playWithCar) {
|
||||
if (car->animState.get_item(3))
|
||||
car->closeDoor(2);
|
||||
else
|
||||
car->openDoor(2);
|
||||
}
|
||||
break;
|
||||
case '4':
|
||||
if (playWithCar) {
|
||||
if (car->animState.get_item(4))
|
||||
car->closeDoor(3);
|
||||
else
|
||||
car->openDoor(3);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ',':
|
||||
if (playWithCar) {
|
||||
car_model -= 1;
|
||||
if (car_model < 0)
|
||||
car_model = 0;
|
||||
}
|
||||
frame_offset -= 1;
|
||||
if (frame_offset < 0)
|
||||
frame_offset = 0;
|
||||
update_anim = true;
|
||||
break;
|
||||
case '.':
|
||||
if (playWithCar) {
|
||||
car_model += 1;
|
||||
if (car_model > 88)
|
||||
car_model = 88;
|
||||
}
|
||||
frame_offset += 1;
|
||||
if (frame_offset >= style.spriteNumbers.countByType(ped.sprType))
|
||||
frame_offset -= 1;
|
||||
update_anim = true;
|
||||
break;
|
||||
case 'n':
|
||||
if (playWithCar) {
|
||||
car_remap -= 1;
|
||||
if (car_remap < -1)
|
||||
car_remap = -1;
|
||||
INFO << "remap: " << int(car_remap) << std::endl;
|
||||
}
|
||||
do {
|
||||
spr_type -= 1;
|
||||
if (spr_type < 0)
|
||||
@ -185,6 +328,12 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
update_anim = 1;
|
||||
break;
|
||||
case 'm':
|
||||
if (playWithCar) {
|
||||
car_remap += 1;
|
||||
if (car_remap > 11)
|
||||
car_remap = 11;
|
||||
INFO << "remap: " << int(car_remap) << std::endl;
|
||||
}
|
||||
do {
|
||||
spr_type += 1;
|
||||
if (spr_type > 20)
|
||||
@ -195,6 +344,11 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
frame_offset = 0;
|
||||
update_anim = 1;
|
||||
break;
|
||||
case 's':
|
||||
if (playWithCar) {
|
||||
car->setSirenAnim(true);
|
||||
}
|
||||
break;
|
||||
case SDLK_F2:
|
||||
bbox_toggle = (bbox_toggle ? 0 : 1);
|
||||
OpenGTA::SpriteManagerHolder::Instance().setDrawBBox(bbox_toggle);
|
||||
@ -205,9 +359,21 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
break;
|
||||
case SDLK_F5:
|
||||
first_offset = frame_offset;
|
||||
std::cout << "First frame: " << first_offset << std::endl;
|
||||
break;
|
||||
case SDLK_F6:
|
||||
second_offset = frame_offset;
|
||||
std::cout << "Last frame: " << second_offset << std::endl;
|
||||
break;
|
||||
case SDLK_F7:
|
||||
play_anim = (play_anim ? false : true);
|
||||
if (play_anim)
|
||||
std::cout << "Playing: " << first_offset << " .. " << second_offset << std::endl;
|
||||
now_frame = first_offset;
|
||||
break;
|
||||
case SDLK_F8:
|
||||
playWithCar = playWithCar ? false : true;
|
||||
update_anim = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -215,6 +381,8 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
if (update_anim) {
|
||||
pedAnim.firstFrameOffset = frame_offset;
|
||||
ped.anim = pedAnim;
|
||||
if (playWithCar)
|
||||
safe_try_model(car_model);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,8 +393,18 @@ void usage(const char* a0) {
|
||||
" + - : zoom in/out" << std::endl <<
|
||||
" , . : previous/next frame offset" << std::endl <<
|
||||
" n m : previous/next sprite-type" << std::endl <<
|
||||
" tab : black/white background" << std::endl <<
|
||||
" F2 : toggle BBox drawn" << std::endl <<
|
||||
" F3 : toggle tex-border drawn" << std::endl;
|
||||
" F3 : toggle tex-border drawn" << std::endl <<
|
||||
" F5 : prepare animation: first-frame = current frame" << std::endl <<
|
||||
" F6 : prepare animation: last-frame = current frame" << std::endl <<
|
||||
" F7 : toggle: play frames" << std::endl <<
|
||||
" F8 : toggle: special-car-mode" << std::endl << std::endl <<
|
||||
"In car-mode:" << std::endl <<
|
||||
" , . : choose model" << std::endl <<
|
||||
" n m : choose remap" << std::endl <<
|
||||
" 1, 2, 3, 4 : open car door (if exists)" << std::endl <<
|
||||
" s : toggle siren anim (if exists)" << std::endl;
|
||||
}
|
||||
|
||||
void parse_args(int argc, char* argv[]) {
|
||||
@ -274,7 +452,7 @@ void run_main() {
|
||||
handleKeyPress(&event.key.keysym);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
// handleKeyUp(&event.key.keysym);
|
||||
// handleKeyUp(&event.key.keysym);
|
||||
break;
|
||||
case SDL_VIDEORESIZE:
|
||||
OpenGL::ScreenHolder::Instance().resize(event.resize.w, event.resize.h);
|
||||
|
@ -131,6 +131,7 @@ namespace OpenGTA {
|
||||
car.update(ticks);
|
||||
num_cars++;
|
||||
}
|
||||
num_obj = 0;
|
||||
for (AbstractContainer<SpriteObject>::Storage_T_Iterator i = AbstractContainer<SpriteObject>::objs.begin();
|
||||
i != AbstractContainer<SpriteObject>::objs.end(); ++i) {
|
||||
SpriteObject & obj = (*i);
|
||||
@ -152,11 +153,13 @@ namespace OpenGTA {
|
||||
|
||||
}
|
||||
removeDeadStuff();
|
||||
if (num_peds < 10 && num_peds > 0) {
|
||||
if (num_peds < 50 && num_peds > 2 && ticks - lastCreateTick > 100) {
|
||||
//MapHelper::createPeds(5);
|
||||
Map & map = OpenGTA::MapHolder::Instance().get();
|
||||
lastCreateTick = ticks;
|
||||
while (1) {
|
||||
Util::TupleOfUint8 tu8 = creationArea.getValidCoord();
|
||||
INFO << "testing: " << int(tu8.first) << ", " << int(tu8.second) << std::endl;
|
||||
int k = -1;
|
||||
for (int i = 0; i < map.getNumBlocksAtNew(tu8.first, tu8.second); ++i) {
|
||||
Map::BlockInfo * bi = map.getBlockAtNew(tu8.first, tu8.second, i);
|
||||
@ -174,32 +177,41 @@ namespace OpenGTA {
|
||||
int id = OpenGTA::TypeIdBlackBox::requestId();
|
||||
Sint16 remap = OpenGTA::StyleHolder::Instance().get().getRandomPedRemapNumber();
|
||||
OpenGTA::Pedestrian p(Vector3D(0.3f, 0.5f, 0.3f), pos, id, remap);
|
||||
p.rot = 360 * (rand() / (RAND_MAX + 1.0));
|
||||
OpenGTA::SpriteManagerHolder::Instance().add<Pedestrian>(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define POS_INSIDE_RECT(pos, r) ((pos.x >= r.x) && \
|
||||
(pos.x <= r.x + r.w) && (pos.z >= r.y) && (pos.z <= r.y + r.h))
|
||||
|
||||
void SpriteManager::drawInRect(SDL_Rect & r) {
|
||||
for (AbstractContainer<Pedestrian>::Storage_T_Iterator i = AbstractContainer<Pedestrian>::objs.begin();
|
||||
i != AbstractContainer<Pedestrian>::objs.end(); ++i) {
|
||||
Pedestrian & ped = (*i);
|
||||
if ((ped.pos.x >= r.x) && (ped.pos.x <= r.x + r.w) &&
|
||||
(ped.pos.z >= r.y) && (ped.pos.z <= r.y + r.h))
|
||||
if (POS_INSIDE_RECT(ped.pos, r))
|
||||
//if ((ped.pos.x >= r.x) && (ped.pos.x <= r.x + r.w) &&
|
||||
// (ped.pos.z >= r.y) && (ped.pos.z <= r.y + r.h))
|
||||
draw(ped);
|
||||
else
|
||||
removePed(ped.id());
|
||||
}
|
||||
for (AbstractContainer<SpriteObject>::Storage_T_Iterator i = AbstractContainer<SpriteObject>::objs.begin();
|
||||
i != AbstractContainer<SpriteObject>::objs.end(); ++i) {
|
||||
SpriteObject & obj = (*i);
|
||||
if ((obj.pos.x >= r.x) && (obj.pos.x <= r.x + r.w) &&
|
||||
(obj.pos.z >= r.y) && (obj.pos.z <= r.y + r.h))
|
||||
//if ((obj.pos.x >= r.x) && (obj.pos.x <= r.x + r.w) &&
|
||||
// (obj.pos.z >= r.y) && (obj.pos.z <= r.y + r.h))
|
||||
if (POS_INSIDE_RECT(obj.pos, r))
|
||||
draw(obj);
|
||||
}
|
||||
for (AbstractContainer<Car>::Storage_T_Iterator i = AbstractContainer<Car>::objs.begin();
|
||||
i != AbstractContainer<Car>::objs.end(); ++i) {
|
||||
Car & car = (*i);
|
||||
if ((car.pos.x >= r.x) && (car.pos.x <= r.x + r.w) &&
|
||||
(car.pos.z >= r.y) && (car.pos.z <= r.y + r.h))
|
||||
// if ((car.pos.x >= r.x) && (car.pos.x <= r.x + r.w) &&
|
||||
// (car.pos.z >= r.y) && (car.pos.z <= r.y + r.h))
|
||||
if (POS_INSIDE_RECT(car.pos, r))
|
||||
draw(car);
|
||||
}
|
||||
|
||||
@ -207,8 +219,7 @@ namespace OpenGTA {
|
||||
typedef ProjectileListType::iterator ProjectileIterator;
|
||||
for (ProjectileIterator i = activeProjectiles.begin(); i != activeProjectiles.end(); ++i) {
|
||||
Projectile & prj = (*i);
|
||||
if ((prj.pos.x >= r.x) && (prj.pos.x <= r.x + r.w) &&
|
||||
(prj.pos.z >= r.y) && (prj.pos.z <= r.y + r.h))
|
||||
if (POS_INSIDE_RECT(prj.pos, r))
|
||||
draw(prj);
|
||||
}
|
||||
glColor3f(1, 1, 1);
|
||||
@ -230,13 +241,13 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
#define GL_OBJ_COMMON(o) GL_CHECKERROR; \
|
||||
glPushMatrix(); \
|
||||
glPushMatrix(); \
|
||||
glTranslatef(o.pos.x, o.pos.y, o.pos.z); \
|
||||
glRotatef(o.rot, 0, 1, 0); \
|
||||
//glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)o.m_M.m)
|
||||
|
||||
#define DRAW_TEX_QUADS_OBJ(t, w, h) glBindTexture(GL_TEXTURE_2D, t.inPage); \
|
||||
glBegin(GL_QUADS); \
|
||||
glBegin(GL_QUADS); \
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v); \
|
||||
glVertex3f(-w/2, 0.0f, h/2); \
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v); \
|
||||
@ -252,23 +263,30 @@ void SpriteManager::draw(Car & car) {
|
||||
GL_OBJ_COMMON(car);
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
OpenGL::PagedTexture t;
|
||||
PHYSFS_uint16 sprNum = style.spriteNumbers.reIndex(car.sprNum +
|
||||
car.anim.firstFrameOffset + car.anim.currentFrame, car.sprType);
|
||||
PHYSFS_uint16 sprNum = style.spriteNumbers.reIndex(car.sprNum, car.sprType);
|
||||
//+ car.anim.firstFrameOffset + car.anim.currentFrame, car.sprType);
|
||||
|
||||
GraphicsBase::SpriteInfo * info = style.getSprite(sprNum);
|
||||
assert(info);
|
||||
float w = float(info->w) / 64.0f;
|
||||
float h = float(info->h) / 64.0f;
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(sprNum, car.remap))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(sprNum, car.remap);
|
||||
OpenGL::SpriteIdentifier si(sprNum, car.remap, car.delta);
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(si))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(si);
|
||||
else {
|
||||
t = OpenGL::SpriteCacheHolder::Instance().create(car.sprNum +
|
||||
car.anim.firstFrameOffset + car.anim.currentFrame,
|
||||
car.sprType, car.remap);
|
||||
t = OpenGL::SpriteCacheHolder::Instance().create(car.sprNum,// +
|
||||
//car.anim.firstFrameOffset + car.anim.currentFrame,
|
||||
car.sprType, car.remap, car.delta);
|
||||
}
|
||||
|
||||
DRAW_TEX_QUADS_OBJ(t, w, h);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(car.carInfo.door[0].rpx / 64.0f, 0.1f, car.carInfo.door[0].rpy / 64.0f);
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (getDrawBBox() || getDrawTexBorder())
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
@ -305,8 +323,8 @@ void SpriteManager::drawTextureOutline(const float & w, const float & h) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glColor3f(float(202)/255.0f, float(31)/255.0f, float(123)/255.0f);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glVertex3f(w/2, 0.0f, h/2);
|
||||
glVertex3f(w/2, 0.0f, -h/2);
|
||||
glVertex3f( w/2, 0.0f, h/2);
|
||||
glVertex3f( w/2, 0.0f, -h/2);
|
||||
glVertex3f(-w/2, 0.0f, -h/2);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glEnd();
|
||||
@ -520,7 +538,7 @@ void SpriteManager::drawExplosion(SpriteObject & obj) {
|
||||
}
|
||||
|
||||
/*
|
||||
void SpriteManager::draw(TrainSegment & train) {
|
||||
void SpriteManager::draw(TrainSegment & train) {
|
||||
GL_OBJ_COMMON(train);
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
|
||||
@ -555,8 +573,8 @@ void SpriteManager::draw(TrainSegment & train) {
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
*/
|
||||
}
|
||||
*/
|
||||
|
||||
void SpriteManager::draw(Projectile & proj) {
|
||||
//GL_OBJ_COMMON(proj); // can't use; not derived from OBox
|
||||
@ -582,92 +600,21 @@ void SpriteManager::draw(Projectile & proj) {
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
void SpriteManager::addPed(Pedestrian & ped) {
|
||||
activePeds.push_back(ped);
|
||||
}
|
||||
|
||||
Pedestrian & SpriteManager::getPedById(const Uint32 & id) {
|
||||
PedListType::iterator i = activePeds.begin();
|
||||
while (i != activePeds.end()) {
|
||||
if (i->pedId == id)
|
||||
return *i;
|
||||
++i;
|
||||
}
|
||||
assert(0);
|
||||
return *activePeds.begin();
|
||||
}
|
||||
|
||||
TrainSegment & SpriteManager::getTrainById(const Uint32 & id) {
|
||||
TrainListType::iterator i = activeTrains.begin();
|
||||
while (i != activeTrains.end()) {
|
||||
if (i->trainId == id)
|
||||
return *i;
|
||||
++i;
|
||||
}
|
||||
assert(0);
|
||||
return *activeTrains.begin();
|
||||
}
|
||||
|
||||
void SpriteManager::removePedById(const Uint32 & id) {
|
||||
PedListType::iterator i = activePeds.begin();
|
||||
while (i != activePeds.end()) {
|
||||
if (i->pedId == id) {
|
||||
activePeds.erase(i);
|
||||
return;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
WARN << "didn't find ped id " << id << " -- cannot remove"<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
void SpriteManager::addCar(Car & car) {
|
||||
activeCars.push_back(car);
|
||||
}
|
||||
|
||||
Car & SpriteManager::getCarById(const Uint32 & id) {
|
||||
CarListType::iterator i = activeCars.begin();
|
||||
while (i != activeCars.end()) {
|
||||
if (i->carId == id) {
|
||||
return *i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
assert(0);
|
||||
return *activeCars.begin();
|
||||
}
|
||||
|
||||
void SpriteManager::addObject(GameObject & go) {
|
||||
activeObjects.push_back(go);
|
||||
}
|
||||
|
||||
void SpriteManager::createExplosion(Vector3D center) {
|
||||
GameObject exp(center, 0, GraphicsBase::SpriteNumbers::EX);
|
||||
exp.anim = SpriteObject::Animation(getAnimationById(99));
|
||||
exp.anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::LOOP);
|
||||
INFO << exp.anim.currentFrame << " " << exp.anim.numFrames << " " << exp.anim.delay << std::endl;
|
||||
activeObjects.push_back(exp);
|
||||
}
|
||||
|
||||
GameObject & SpriteManager::getObjectById(const Uint32 & id) {
|
||||
ObjectListType::iterator i = activeObjects.begin();
|
||||
while (i != activeObjects.end()) {
|
||||
if (i->objId == id) {
|
||||
return *i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
assert(0);
|
||||
return *activeObjects.begin();
|
||||
}
|
||||
*/
|
||||
|
||||
void SpriteManager::removeDeadStuff() {
|
||||
AbstractContainer<Pedestrian>::doRealRemove();
|
||||
AbstractContainer<Car>::doRealRemove();
|
||||
AbstractContainer<SpriteObject>::doRealRemove();
|
||||
AbstractContainer<Pedestrian>::Storage_T_Iterator i = AbstractContainer<Pedestrian>::objs.begin();
|
||||
while (i != AbstractContainer<Pedestrian>::objs.end()) {
|
||||
Pedestrian & ped = (*i);
|
||||
if ((ped.isDead == 3) && (creationArea.isOnScreen(ped.pos) == false)) {
|
||||
AbstractContainer<Pedestrian>::Storage_T_Iterator j = i; j++;
|
||||
AbstractContainer<Pedestrian>::objs.erase(i);
|
||||
i = j;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
SpriteObject::Animation & SpriteManager::getAnimationById(const Uint32 & id) {
|
||||
|
@ -179,6 +179,7 @@ namespace OpenGTA {
|
||||
|
||||
private:
|
||||
Uint32 drawMode;
|
||||
Uint32 lastCreateTick;
|
||||
|
||||
//SpriteManager(const SpriteManager & o) : trainSystem(AbstractContainer<TrainSegment>::objs) {assert(0);}
|
||||
SpriteManager(const SpriteManager & o) {assert(0);}
|
||||
|
49
tests/lua_map_test.cpp
Normal file
49
tests/lua_map_test.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <string>
|
||||
#include "lua_vm.h"
|
||||
#include "opengta.h"
|
||||
#include "dataholder.h"
|
||||
#include "file_helper.h"
|
||||
#include "log.h"
|
||||
|
||||
std::string map_filename;
|
||||
const char* script_file;
|
||||
|
||||
void on_exit() {
|
||||
SDL_Quit();
|
||||
PHYSFS_deinit();
|
||||
}
|
||||
|
||||
void parse_args(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
ERROR << "invalid args" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
map_filename = std::string(argv[1]);
|
||||
script_file = argv[2];
|
||||
}
|
||||
|
||||
void run_init(const char* prg_name) {
|
||||
PHYSFS_init(prg_name);
|
||||
|
||||
Util::FileHelper & fh = GET_FILE_HELPER;
|
||||
if (fh.existsInSystemFS(fh.getBaseDataPath())) {
|
||||
PHYSFS_addToSearchPath(GET_FILE_HELPER.getBaseDataPath().c_str(), 1);
|
||||
}
|
||||
else {
|
||||
WARN << "Could not load data-source: " << fh.getBaseDataPath() << std::endl;
|
||||
}
|
||||
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
|
||||
}
|
||||
|
||||
void run_main() {
|
||||
OpenGTA::Script::LuaVM & vm = OpenGTA::Script::LuaVMHolder::Instance();
|
||||
|
||||
OpenGTA::MainMsgHolder::Instance().load("ENGLISH.FXT");
|
||||
OpenGTA::MapHolder::Instance().load(map_filename);
|
||||
OpenGTA::Map & loadedMap = OpenGTA::MapHolder::Instance().get();
|
||||
vm.setMap(loadedMap);
|
||||
|
||||
vm.runFile(script_file);
|
||||
}
|
43
tests/plot_interpolate.sh
Normal file
43
tests/plot_interpolate.sh
Normal file
@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
function input_data() {
|
||||
cat <<EOF
|
||||
0
|
||||
1
|
||||
2
|
||||
1
|
||||
0
|
||||
-1
|
||||
-2
|
||||
-1
|
||||
0
|
||||
1
|
||||
2
|
||||
1
|
||||
0
|
||||
-1
|
||||
-2
|
||||
-1
|
||||
0
|
||||
EOF
|
||||
}
|
||||
|
||||
function transform() {
|
||||
switch=$1
|
||||
input_data | ./interpolate_test --$switch >gnuplot_data.$$
|
||||
cat <<EOF >gnuplot_script.$$
|
||||
plot "gnuplot_data.$$" title "$switch"
|
||||
EOF
|
||||
gnuplot gnuplot_script.$$ -
|
||||
}
|
||||
|
||||
if [ ! -f interpolate_test ]; then
|
||||
g++ -I ../math -o interpolate_test interpolate_test.cpp
|
||||
fi
|
||||
|
||||
transform linear
|
||||
transform cubic
|
||||
transform cosine
|
||||
transform hermite
|
||||
|
||||
rm -f gnuplot_data.$$ gnuplot_script.$$
|
75
tests/rectangle.cpp
Normal file
75
tests/rectangle.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include <iostream>
|
||||
#include "rectangle.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Math;
|
||||
|
||||
template <typename T> bool test_values ( const Rectangle<T> & r, T x, T y, T w, T h ) {
|
||||
return (r.x == x && r.y == y && r.w == w && r.h == h);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
/*
|
||||
#define TEST_SET_1 5, 10, 24, 31
|
||||
Rectangle<int> a(TEST_SET_1);
|
||||
if (!test_values<int>(a, TEST_SET_1))
|
||||
cerr << "verifying values failed " << __LINE__ << endl;
|
||||
|
||||
Rectangle<int> a_copy(a);
|
||||
if (!test_values<int>(a_copy, TEST_SET_1))
|
||||
cerr << "copy-constructor failed " << __LINE__ << endl;
|
||||
|
||||
if (! (a == a_copy) )
|
||||
cerr << "equality failed " << __LINE__ << endl;
|
||||
|
||||
if (! a.isInside(15, 15) )
|
||||
cerr << "isInside failed " << __LINE__ << endl;
|
||||
|
||||
|
||||
Rectangle<int> b(10, 15, 10, 15);
|
||||
if (a == b )
|
||||
cerr << "equality failed " << __LINE__ << endl;
|
||||
|
||||
if (! rectangle_test_inside<int>(a, b) )
|
||||
cerr << "rect-inside-rect test failed " << __LINE__ << endl;
|
||||
|
||||
if (rectangle_test_leftborder<int>(a, b))
|
||||
cerr << "rectangle-left-b failed " << __LINE__ << endl;
|
||||
|
||||
if (rectangle_test_rightborder<int>(a, b))
|
||||
cerr << "rectangle-right-b failed " << __LINE__ << endl;
|
||||
|
||||
if (rectangle_test_topborder<int>(a, b))
|
||||
cerr << "rectangle-top-b failed " << __LINE__ << endl;
|
||||
|
||||
if (rectangle_test_bottomborder<int>(a, b))
|
||||
cerr << "rectangle-bottom-b failed " << __LINE__ << endl;
|
||||
|
||||
*/
|
||||
|
||||
typedef Rectangle<int> IRect;
|
||||
|
||||
int input[4];
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
input[j] = 0;
|
||||
input[j] = atoi(argv[j+1]);
|
||||
}
|
||||
|
||||
IRect big(input[0], input[1], input[2], input[3]);
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
input[j] = 0;
|
||||
input[j] = atoi(argv[j+5]);
|
||||
}
|
||||
|
||||
|
||||
IRect small(input[0], input[1], input[2], input[3]);
|
||||
list< IRect > mlist;
|
||||
RectangleGeometry<int>::difference(mlist, big, small);
|
||||
|
||||
cout << mlist.size() << " rects returned" << endl;
|
||||
list< IRect >::iterator i;
|
||||
for (i = mlist.begin(); i != mlist.end(); ++i) {
|
||||
cout << "x = " << i->x << " y = " << i->y
|
||||
<< " w = " << i->w << " h = " << i->h << endl;
|
||||
}
|
||||
}
|
@ -1,62 +1,38 @@
|
||||
#include <iostream>
|
||||
#include <SDL_opengl.h>
|
||||
#include "common_sdl_gl.h"
|
||||
#include "opengta.h"
|
||||
#include "gl_texturecache.h"
|
||||
#include "dataholder.h"
|
||||
#include "gl_screen.h"
|
||||
#include "gl_camera.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
class MapViewGL {
|
||||
private:
|
||||
Map* currentMap;
|
||||
Graphics8Bit* styleDB;
|
||||
OpenGL::TextureCache<uint8_t>* sideCache;
|
||||
OpenGL::TextureCache<uint8_t>* lidCache;
|
||||
public:
|
||||
MapViewGL();
|
||||
~MapViewGL();
|
||||
int loadMap(const std::string &map, const std::string &style);
|
||||
void drawMap(int32_t x, int32_t y, int32_t dx, int32_t dy);
|
||||
void drawBlock(Map::BlockInfo* bi);
|
||||
};
|
||||
}
|
||||
Uint32 arg_screen_w = 0;
|
||||
Uint32 arg_screen_h = 0;
|
||||
std::string map_file("NYC.CMP");
|
||||
Vector3D e(3, 3, 3);
|
||||
Vector3D c(0.5f, 0.5f, 0.5f);
|
||||
Vector3D u(0, 1, 0);
|
||||
uint8_t which = 0;
|
||||
float r = 0;
|
||||
bool wireframe = true;
|
||||
|
||||
namespace OpenGTA {
|
||||
MapViewGL::MapViewGL() {
|
||||
currentMap = NULL;
|
||||
styleDB = NULL;
|
||||
sideCache = NULL;
|
||||
lidCache = NULL;
|
||||
}
|
||||
MapViewGL::~MapViewGL() {
|
||||
if (currentMap)
|
||||
delete currentMap;
|
||||
if (styleDB)
|
||||
delete styleDB;
|
||||
if (sideCache)
|
||||
delete sideCache;
|
||||
if (lidCache)
|
||||
delete lidCache;
|
||||
}
|
||||
int MapViewGL::loadMap(const std::string &map, const std::string &style) {
|
||||
currentMap = new Map(map);
|
||||
styleDB = new Graphics8Bit(style);
|
||||
sideCache = new OpenGL::TextureCache<uint8_t>();
|
||||
lidCache = new OpenGL::TextureCache<uint8_t>();
|
||||
//currentMap->dump();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
extern SDL_Surface* screen;
|
||||
GLfloat mapPos[3] = {12.0f, 12.0f, 20.0f};
|
||||
GLfloat camVec[3] = {0.0f, 1.0f, 0.0f};
|
||||
|
||||
OpenGTA::MapViewGL *map = NULL;
|
||||
extern int global_EC;
|
||||
extern int global_Done;
|
||||
|
||||
|
||||
const size_t numBlockTypes = 53;
|
||||
const size_t numFaces = 5;
|
||||
|
||||
float slope_raw_data[numBlockTypes][numFaces][4][3] = {
|
||||
#include "slope2_data.h"
|
||||
};
|
||||
|
||||
#define SLOPE_RAW_DATA slope_raw_data
|
||||
|
||||
|
||||
void on_exit() {
|
||||
SDL_FreeSurface(screen);
|
||||
SDL_Quit();
|
||||
if (map)
|
||||
delete map;
|
||||
PHYSFS_deinit();
|
||||
if (global_EC)
|
||||
std::cerr << "Exiting after fatal problem - please see output above" << std::endl;
|
||||
@ -64,254 +40,170 @@ void on_exit() {
|
||||
std::cout << "Goodbye" << std::endl;
|
||||
}
|
||||
|
||||
void print_usage(const char*) {
|
||||
}
|
||||
|
||||
void parse_args(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
void handleKeyPress( SDL_keysym *keysym ) {
|
||||
switch ( keysym->sym ) {
|
||||
case SDLK_ESCAPE:
|
||||
global_Done = 1;
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
mapPos[0] += 1.0f;
|
||||
r -= 10;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
mapPos[0] -= 1.0f;
|
||||
if (mapPos[0] < 0.0f)
|
||||
mapPos[0] = 0.0f;
|
||||
r += 10;
|
||||
break;
|
||||
case SDLK_SPACE:
|
||||
wireframe = (wireframe) ? false : true;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
mapPos[1] += 1.0f;
|
||||
which++;
|
||||
if (which >= numBlockTypes)
|
||||
which = numBlockTypes - 1;
|
||||
INFO << "slope-type: " << int(which) << std::endl;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
mapPos[1] -= 1.0f;
|
||||
if (mapPos[1] < 0.0f)
|
||||
mapPos[1] = 0.0f;
|
||||
break;
|
||||
case '+':
|
||||
mapPos[2] += 1.0f;
|
||||
break;
|
||||
case '-':
|
||||
mapPos[2] -= 1.0f;
|
||||
break;
|
||||
case 'x':
|
||||
camVec[0] = 1.0f; camVec[1] = 0.0f; camVec[2] = 0.0f;
|
||||
break;
|
||||
case 'y':
|
||||
camVec[0] = 0.0f; camVec[1] = 1.0f; camVec[2] = 0.0f;
|
||||
break;
|
||||
case 'z':
|
||||
camVec[0] = 0.0f; camVec[1] = 0.0f; camVec[2] = 1.0f;
|
||||
if (which > 0)
|
||||
which--;
|
||||
INFO << "slope-type: " << int(which) << std::endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint createGLTexture(GLsizei w, GLsizei h, const void* pixels) {
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, param);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, param);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// GL_LINEAR_MIPMAP_LINEAR);
|
||||
/*gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, w,
|
||||
h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
||||
*/
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
return tex;
|
||||
}
|
||||
|
||||
void OpenGTA::MapViewGL::drawBlock(OpenGTA::Map::BlockInfo* bi) {
|
||||
float size = 0.5f;
|
||||
int jj = 0;
|
||||
if (bi == NULL)
|
||||
return;
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
if (bi->left) {
|
||||
// Left Face
|
||||
if (!sideCache->hasTexture(bi->left)) {
|
||||
styleDB->getSide(static_cast<unsigned int>(bi->left-1), 0, true);
|
||||
sideCache->addTexture(bi->left, createGLTexture(64, 64, &styleDB->tileTmpRGBA));
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, sideCache->getTextureWithId(bi->left));
|
||||
//}
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
//glNormal3f(-1.0f, 0.0f, 0.0f);
|
||||
glVertex3f(-size, -size, -size);// Bottom Left Of The Texture and Quad
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(-size, -size, size);// Bottom Right Of The Texture and Quad
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(-size, size, size);// Top Right Of The Texture and Quad
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f(-size, size, -size);// Top Left Of The Texture and Quad
|
||||
glEnd();
|
||||
}
|
||||
if (bi->right) {
|
||||
// Right face
|
||||
if (!sideCache->hasTexture(bi->right)) {
|
||||
styleDB->getSide(static_cast<unsigned int>(bi->right-1), 0, true);
|
||||
sideCache->addTexture(bi->right, createGLTexture(64, 64, &styleDB->tileTmpRGBA));
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, sideCache->getTextureWithId(bi->right));
|
||||
//}
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
//glNormal3f(1.0f, 0.0f, 0.0f);
|
||||
glVertex3f( size, -size, -size);// Bottom Right Of The Texture and Quad
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f( size, size, -size);// Top Right Of The Texture and Quad
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f( size, size, size);// Top Left Of The Texture and Quad
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f( size, -size, size);// Bottom Left Of The Texture and Quad
|
||||
glEnd();
|
||||
}
|
||||
if (bi->top) {
|
||||
// Back Face
|
||||
if (!sideCache->hasTexture(bi->top)) {
|
||||
styleDB->getSide(static_cast<unsigned int>(bi->top-1), 0, true);
|
||||
sideCache->addTexture(bi->top, createGLTexture(64, 64, &styleDB->tileTmpRGBA));
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, sideCache->getTextureWithId(bi->top));
|
||||
//}
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
//glNormal3f(0.0f, 0.0f, 1.0f);
|
||||
glVertex3f(-size, size, -size);// Top Left Of The Texture and Quad
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-size, size, size);// Bottom Left Of The Texture and Quad
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f( size, size, size);// Bottom Right Of The Texture and Quad
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f( size, size, -size);// Top Right Of The Texture and Quad
|
||||
glEnd();
|
||||
}
|
||||
if (bi->bottom) {
|
||||
// Front Face
|
||||
if (!sideCache->hasTexture(bi->bottom)) {
|
||||
styleDB->getSide(static_cast<unsigned int>(bi->bottom-1), 0, true);
|
||||
sideCache->addTexture(bi->bottom, createGLTexture(64, 64, &styleDB->tileTmpRGBA));
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, sideCache->getTextureWithId(bi->bottom));
|
||||
//}
|
||||
glBegin(GL_QUADS);
|
||||
//glNormal3f(0.0f, 0.0f, -1.0f);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex3f(-size, -size, -size);// Top Right Of The Texture and Quad
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex3f( size, -size, -size);// Top Left Of The Texture and Quad
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f( size, -size, size);// Bottom Left Of The Texture and Quad
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex3f(-size, -size, size);// Bottom Right Of The Texture and Quad
|
||||
glEnd();
|
||||
}
|
||||
if (bi->lid) {
|
||||
// Top Face
|
||||
if (!lidCache->hasTexture(bi->lid)) {
|
||||
styleDB->getLid(static_cast<unsigned int>(bi->lid-1), 0, true);
|
||||
lidCache->addTexture(bi->lid, createGLTexture(64, 64, &styleDB->tileTmpRGBA));
|
||||
}
|
||||
if (bi->typeMapExt & 128) {
|
||||
//std::cout << "blending!" << std::endl;
|
||||
}
|
||||
jj = 0;
|
||||
if (bi->typeMap & 16384) {
|
||||
jj += 2;
|
||||
}
|
||||
if (bi->typeMap & 32768) {
|
||||
jj += 4;
|
||||
}
|
||||
GLfloat lidTex[8] = {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
|
||||
#ifdef GLTEX_HELPER
|
||||
#undef GLTEX_HELPER
|
||||
#endif
|
||||
#define GLTEX_HELPER \
|
||||
glTexCoord2f(lidTex[jj], lidTex[jj+1]); jj += 2; if (jj > 6) { jj = 0; }
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, lidCache->getTextureWithId(bi->lid));
|
||||
//}
|
||||
glBegin(GL_QUADS);
|
||||
GLTEX_HELPER;
|
||||
//glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glVertex3f(-size, -size, size);// Bottom Left Of The Texture and Quad
|
||||
GLTEX_HELPER;
|
||||
glVertex3f( size, -size, size);// Bottom Right Of The Texture and Quad
|
||||
GLTEX_HELPER;
|
||||
glVertex3f( size, size, size);// Top Right Of The Texture and Quad
|
||||
GLTEX_HELPER;
|
||||
glVertex3f(-size, size, size);// Top Left Of The Texture and Quad
|
||||
glEnd();
|
||||
#undef GLTEX_HELPER
|
||||
}
|
||||
}
|
||||
void OpenGTA::MapViewGL::drawMap(int32_t x1, int32_t y1, int32_t x2, int32_t y2) {
|
||||
if (x1 < 0)
|
||||
x1 = 0;
|
||||
if (y1 < 0)
|
||||
y1 = 0;
|
||||
|
||||
// FIXME: can't access 255 either x or y... WHY?
|
||||
if (x2 >= 255)
|
||||
x2 = 255;
|
||||
if (y2 >= 255)
|
||||
y2 = 255;
|
||||
|
||||
//std::cout << "draw: " << x1 << " " << y1 << " - " << x2 << " " << y2 << std::endl;
|
||||
sideCache->sink();
|
||||
lidCache->sink();
|
||||
for (int i = y1; i <= y2; i++) {
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0f, -1.0f*i, 0.0f);
|
||||
for (int j= x1; j <= x2; j++) {
|
||||
glPushMatrix();
|
||||
glTranslatef(1.0f*j, 0.0f, 0.0f);
|
||||
PHYSFS_uint16 emptycount = currentMap->getNumBlocksAt(j,i);
|
||||
/*glPushMatrix();
|
||||
* for(int c=0; c < 6 - emptycount-1; c++) */
|
||||
for (int c=6-emptycount-0; c >= 1; c--) {
|
||||
drawBlock(currentMap->getBlockAt(j,i, c));
|
||||
glTranslatef(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
sideCache->clear();
|
||||
lidCache->clear();
|
||||
}
|
||||
|
||||
void drawScene() {
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glLoadIdentity();
|
||||
gluLookAt(mapPos[0], -mapPos[1], mapPos[2], mapPos[0], -mapPos[1], 0.0f, camVec[0], camVec[1], camVec[2]);
|
||||
//map->drawMap(int(mapPos[0]), int(mapPos[1]));
|
||||
map->drawMap(int32_t(mapPos[0])-10, int32_t(mapPos[1])-10,int32_t(mapPos[0])+10, int32_t(mapPos[1])+10);
|
||||
OpenGL::ScreenHolder::Instance().set3DProjection();
|
||||
OpenGL::CameraHolder::Instance().update(1);
|
||||
|
||||
glRotatef(r, 0, 1, 0);
|
||||
glColor3f(0.5f, 1, 0.2f);
|
||||
// lid
|
||||
if (wireframe)
|
||||
glBegin(GL_LINE_STRIP);
|
||||
else
|
||||
glBegin(GL_QUADS);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][0][j][0],
|
||||
SLOPE_RAW_DATA[which][0][j][1],
|
||||
SLOPE_RAW_DATA[which][0][j][2]);
|
||||
}
|
||||
if (wireframe)
|
||||
glVertex3f(SLOPE_RAW_DATA[which][0][0][0],
|
||||
SLOPE_RAW_DATA[which][0][0][1],
|
||||
SLOPE_RAW_DATA[which][0][0][2]);
|
||||
glEnd();
|
||||
|
||||
glColor3f(0.1f, 0.5f, 1);
|
||||
// top
|
||||
if (which != 42 && which != 45) {
|
||||
if (wireframe)
|
||||
glBegin(GL_LINE_STRIP);
|
||||
else
|
||||
glBegin(GL_QUADS);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][2][j][0],
|
||||
SLOPE_RAW_DATA[which][2][j][1],
|
||||
SLOPE_RAW_DATA[which][2][j][2]);
|
||||
}
|
||||
if (wireframe)
|
||||
glVertex3f(SLOPE_RAW_DATA[which][2][0][0],
|
||||
SLOPE_RAW_DATA[which][2][0][1],
|
||||
SLOPE_RAW_DATA[which][2][0][2]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glColor3f(1, 0.2f, 0.5f);
|
||||
// bottom
|
||||
if (which != 41 && which != 46) {
|
||||
if (wireframe)
|
||||
glBegin(GL_LINE_STRIP);
|
||||
else
|
||||
glBegin(GL_QUADS);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][1][j][0],
|
||||
SLOPE_RAW_DATA[which][1][j][1],
|
||||
SLOPE_RAW_DATA[which][1][j][2]);
|
||||
}
|
||||
if (wireframe)
|
||||
glVertex3f(SLOPE_RAW_DATA[which][1][0][0],
|
||||
SLOPE_RAW_DATA[which][1][0][1],
|
||||
SLOPE_RAW_DATA[which][1][0][2]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glColor3f(0.4f, 0.1f, 0.6f);
|
||||
// left
|
||||
if (which != 44 && which != 48) {
|
||||
if (wireframe)
|
||||
glBegin(GL_LINE_STRIP);
|
||||
else
|
||||
glBegin(GL_QUADS);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][3][j][0],
|
||||
SLOPE_RAW_DATA[which][3][j][1],
|
||||
SLOPE_RAW_DATA[which][3][j][2]);
|
||||
}
|
||||
if (wireframe)
|
||||
glVertex3f(SLOPE_RAW_DATA[which][3][0][0],
|
||||
SLOPE_RAW_DATA[which][3][0][1],
|
||||
SLOPE_RAW_DATA[which][3][0][2]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glColor3f(0.8f, 0.6f, 0.2f);
|
||||
// right
|
||||
if (which != 43 && which != 47) {
|
||||
if (wireframe)
|
||||
glBegin(GL_LINE_STRIP);
|
||||
else
|
||||
glBegin(GL_QUADS);
|
||||
for (int j=0; j < 4; j++) {
|
||||
glVertex3f(SLOPE_RAW_DATA[which][4][j][0],
|
||||
SLOPE_RAW_DATA[which][4][j][1],
|
||||
SLOPE_RAW_DATA[which][4][j][2]);
|
||||
}
|
||||
if (wireframe)
|
||||
glVertex3f(SLOPE_RAW_DATA[which][4][0][0],
|
||||
SLOPE_RAW_DATA[which][4][0][1],
|
||||
SLOPE_RAW_DATA[which][4][0][2]);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
void run_init(const char* prg) {
|
||||
PHYSFS_init("blockview");
|
||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
|
||||
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||
screen.activate(arg_screen_w, arg_screen_h);
|
||||
SDL_EnableKeyRepeat( 100, SDL_DEFAULT_REPEAT_INTERVAL );
|
||||
|
||||
OpenGTA::MainMsgHolder::Instance().load("ENGLISH.FXT");
|
||||
OpenGTA::MapHolder::Instance().load(map_file);
|
||||
|
||||
OpenGL::CameraHolder::Instance().setVectors(e, c, u);
|
||||
|
||||
}
|
||||
|
||||
void run_main() {
|
||||
SDL_Event event;
|
||||
int paused = 0;
|
||||
|
||||
PHYSFS_init("mapview");
|
||||
PHYSFS_init("blockview");
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
//glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glEnable(GL_ALPHA_TEST);
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
|
||||
map = new OpenGTA::MapViewGL();
|
||||
map->loadMap("NYC.CMP", "STYLE001.GRY");
|
||||
|
||||
while(!global_Done && !global_EC) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
@ -326,17 +218,11 @@ void run_main() {
|
||||
handleKeyPress(&event.key.keysym);
|
||||
break;
|
||||
case SDL_VIDEORESIZE:
|
||||
screen = SDL_SetVideoMode( event.resize.w,
|
||||
event.resize.h, 32, videoFlags );
|
||||
if (!screen)
|
||||
ERROR("Failed to set video mode after resize event");
|
||||
resize(event.resize.w, event.resize.h);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
global_Done = 1;
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
std::cout << "Mouse move: x " << float(event.motion.x)/screen->w << " y " << float(event.motion.y)/screen->h << std::endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
54
tools/bug_parser.awk
Normal file
54
tools/bug_parser.awk
Normal file
@ -0,0 +1,54 @@
|
||||
BEGIN {
|
||||
in_record = 1
|
||||
bug_num = 0
|
||||
}
|
||||
{
|
||||
if ($1 ~ /^\%\% *$/) {
|
||||
# print "RECORD END"
|
||||
if (length(bug_status) == 0) {
|
||||
bug_status = "open"
|
||||
}
|
||||
if (length(bug_has_image) == 0) {
|
||||
pr_image_str = ""
|
||||
}
|
||||
else {
|
||||
pr_image_str = "image: <a href=\"" bug_has_image "\">" bug_has_image "</a>"
|
||||
}
|
||||
print "<div class=\"a_bug\"><a name=\"bug_" bug_num "\"></a>"
|
||||
print " <span class=\"bug_n\">#" bug_num "</span> <span class=\"bug_t\">" bug_title "</span><br>"
|
||||
print " <span class=\"bug_s\">status: " bug_status "</span> <span>" pr_image_str "</span><br>"
|
||||
print " <span class=\"bug_d\">" bug_descr "</span>"
|
||||
print "</div>"
|
||||
print "<br>"
|
||||
}
|
||||
if ($1 == "Bug:") {
|
||||
sub(/^Bug: /, "", $0)
|
||||
bug_title = $0
|
||||
in_record = 2
|
||||
bug_has_image = ""
|
||||
bug_descr = ""
|
||||
bug_status = ""
|
||||
bug_num = bug_num + 1
|
||||
}
|
||||
else if ($1 == "Image:") {
|
||||
bug_has_image = $2
|
||||
}
|
||||
else if ($1 == "Status:") {
|
||||
bug_status = $2
|
||||
}
|
||||
else {
|
||||
if (in_record == 2) {
|
||||
if (length(bug_descr) > 0) {
|
||||
if (length($0) == 0) {
|
||||
bug_descr = bug_descr "<br>"
|
||||
}
|
||||
else {
|
||||
bug_descr = bug_descr " " $0
|
||||
}
|
||||
}
|
||||
else {
|
||||
bug_descr = $0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
52
tools/build_svg_rect.sh
Executable file
52
tools/build_svg_rect.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
function print_header() {
|
||||
cat <<EOF
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="$WIDTH" height="$HEIGHT" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
EOF
|
||||
}
|
||||
|
||||
function print_rect() {
|
||||
local x=$1
|
||||
local y=$2
|
||||
local w=$3
|
||||
local h=$4
|
||||
local col=$5
|
||||
cat <<EOF
|
||||
<rect x="$x" y="$y" width="$w" height="$h"
|
||||
style="fill:rgb($col);stroke-width:1;
|
||||
stroke:rgb(0,0,0)"/>
|
||||
EOF
|
||||
}
|
||||
|
||||
WIDTH=200
|
||||
HEIGHT=200
|
||||
|
||||
function print_rnd_col() {
|
||||
foo=$(echo "$RANDOM % 4" | bc)
|
||||
case $foo in
|
||||
0)
|
||||
echo "0,0,255";;
|
||||
1)
|
||||
echo "255,0,0";;
|
||||
2)
|
||||
echo "0,255,0";;
|
||||
3)
|
||||
echo "255,255,0";;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
print_header
|
||||
fi
|
||||
while [ $# -gt 0 ]; do
|
||||
col=$(print_rnd_col)
|
||||
print_rect $1 $2 $3 $4 $col
|
||||
shift;shift;shift;shift
|
||||
done
|
||||
|
||||
echo '</svg>'
|
86
tools/car_dump.cpp
Normal file
86
tools/car_dump.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "opengta.h"
|
||||
#include "dataholder.h"
|
||||
|
||||
extern int global_EC;
|
||||
extern int global_Done;
|
||||
std::string map_file("undefined_map_file");
|
||||
std::string style_file("undefined_style_file");
|
||||
std::string msg_file("ENGLISH.FXT");
|
||||
|
||||
void on_exit() {
|
||||
PHYSFS_deinit();
|
||||
if (global_EC)
|
||||
std::cerr << "Exiting after fatal problem - please see output above" << std::endl;
|
||||
}
|
||||
|
||||
void parse_args(int argc, char* argv[]) {
|
||||
#ifdef DUMP_CARS_IN_MAP
|
||||
if (argc != 3) {
|
||||
std::cout << "USAGE: " << argv[0] << " map-file style-file" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
map_file = argv[1];
|
||||
style_file = argv[2];
|
||||
#else
|
||||
if (argc != 2) {
|
||||
std::cout << "USAGE: " << argv[0] << " style-file" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
map_file = "";
|
||||
style_file = argv[1];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void print_car(OpenGTA::GraphicsBase::CarInfo & ci) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "car" << int(ci.model);
|
||||
#define PRINT(c) << #c << ":" << ci.c << "|"
|
||||
#define PRINTC(c) << #c << ":" << int(ci.c) << "|"
|
||||
std::cout PRINT(width) PRINT(height) PRINT(depth)
|
||||
PRINT(sprNum) PRINT(weightDescriptor) PRINT(maxSpeed) PRINT(minSpeed)
|
||||
PRINT(acceleration) PRINT(braking) PRINT(grip) PRINT(handling)
|
||||
// remaps
|
||||
PRINTC(vtype) PRINTC(model) PRINTC(turning) PRINTC(damagable) <<
|
||||
"model-name:" << OpenGTA::MainMsgHolder::Instance().get().getText(ostr.str()) << "|"
|
||||
PRINTC(cx) PRINTC(cy) PRINT(moment)
|
||||
PRINT(rbpMass) PRINT(g1_Thrust) PRINT(tyreAdhesionX) PRINT(tyreAdhesionY)
|
||||
PRINT(handBrakeFriction) PRINT(footBrakeFriction) PRINT(frontBrakeBias)
|
||||
PRINT(turnRatio) PRINT(driveWheelOffset) PRINT(steeringWheelOffset)
|
||||
PRINT(backEndSlideValue) PRINT(handBrakeSlideValue)
|
||||
PRINTC(convertible) PRINTC(engine) PRINTC(radio) PRINTC(horn) PRINTC(soundFunction)
|
||||
PRINTC(fastChangeFlag) PRINT(numDoors);
|
||||
#undef PRINT
|
||||
#define PRINT(c) << #c << ":" << ci.door[i].c << "|"
|
||||
for (int i = 0; i < ci.numDoors; i++) {
|
||||
std::cout PRINT(rpx) PRINT(rpy) PRINT(object) PRINT(delta);
|
||||
}
|
||||
std::cout << "remap8:";
|
||||
for (int i = 0 ; i < 12; i++) {
|
||||
std::cout << int(ci.remap8[i]) << (i < 11 ? "," : "");
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void run_init(const char*) {
|
||||
PHYSFS_init("mapview");
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||
}
|
||||
|
||||
// dump all cars in style
|
||||
void run_main() {
|
||||
OpenGTA::MainMsgHolder::Instance().load(msg_file);
|
||||
OpenGTA::StyleHolder::Instance().load(style_file);
|
||||
OpenGTA::GraphicsBase & style = OpenGTA::StyleHolder::Instance().get();
|
||||
std::cout << "DUMP_OBJ_INFO BEGIN" << std::endl;
|
||||
for (size_t i = 0; i < style.carInfos.size(); ++i) {
|
||||
OpenGTA::GraphicsBase::CarInfo * cinfo = style.carInfos[i];
|
||||
assert(cinfo);
|
||||
print_car(*cinfo);
|
||||
}
|
||||
|
||||
}
|
90
tools/fxt.c
Normal file
90
tools/fxt.c
Normal file
@ -0,0 +1,90 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void encode();
|
||||
void decode();
|
||||
int count = 0;
|
||||
|
||||
void usage(const char* prg) {
|
||||
printf("USAGE: %s [-e | -d] < src_file > target_file\n", prg);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int mode = 0;
|
||||
if (argc == 2) {
|
||||
if (argv[1][1] == 'd')
|
||||
mode = 1;
|
||||
if (argv[1][1] == 'e')
|
||||
mode = 2;
|
||||
}
|
||||
else
|
||||
usage(argv[0]);
|
||||
|
||||
switch (mode) {
|
||||
case 1:
|
||||
decode();
|
||||
break;
|
||||
case 2:
|
||||
encode();
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void decode() {
|
||||
int c;
|
||||
int addVal = 0;
|
||||
while ((c = getchar()) != EOF) {
|
||||
c--;
|
||||
if (count <= 7)
|
||||
c -= (0x63 << count);
|
||||
if (c == 195) {
|
||||
addVal = 64;
|
||||
// fprintf(stderr, "addval after %i bytes\n", count);
|
||||
}
|
||||
else {
|
||||
c += addVal;
|
||||
/* if (addVal)
|
||||
fprintf(stderr, "decoding-addval %i %i\n", c, c - addVal);
|
||||
else
|
||||
fprintf(stderr, "decoding: %i\n", (unsigned char)c);
|
||||
*/
|
||||
addVal = 0;
|
||||
if (c == 0)
|
||||
c = '\n';
|
||||
putchar(c);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
void encode_out(int v) {
|
||||
if (count <= 7)
|
||||
v += (0x63 << count);
|
||||
v++;
|
||||
putchar(v);
|
||||
}
|
||||
|
||||
void encode() {
|
||||
int c;
|
||||
count = 0;
|
||||
while ((c = getchar()) != EOF) {
|
||||
if (c == '\n') {
|
||||
c = 0;
|
||||
}
|
||||
|
||||
if (c >= 192) {
|
||||
int _c = 195;
|
||||
encode_out(_c);
|
||||
c -= 64;
|
||||
encode_out(c);
|
||||
}
|
||||
else {
|
||||
encode_out(c);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
10
tools/label_screenshot.sh
Normal file
10
tools/label_screenshot.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
in=$1
|
||||
|
||||
out=$1.new
|
||||
|
||||
|
||||
convert $in -fill white -box '#00000080' \
|
||||
-gravity North -annotate +0+10 ' ~Scumbag City~ by Pennywise ' \
|
||||
-pointsize 20 $out
|
@ -1,7 +1,60 @@
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include "opengta.h"
|
||||
#include "dataholder.h"
|
||||
#include "log.h"
|
||||
|
||||
uint32_t green = 0x00dd00ff;
|
||||
uint32_t red = 0xdd0000ff;
|
||||
uint32_t blue = 0x0000ddff;
|
||||
|
||||
uint32_t field = green;
|
||||
uint32_t building = 0xdf9f6fff;
|
||||
uint32_t water = blue;
|
||||
uint32_t road = 0xdadadaff;
|
||||
uint32_t pavement = 0x8a9aa0ff;
|
||||
|
||||
uint32_t map_color[] = {
|
||||
0x000000ff,
|
||||
water,
|
||||
road,
|
||||
pavement,
|
||||
field,
|
||||
building,
|
||||
0xffffffff,
|
||||
0xff0000ff
|
||||
};
|
||||
|
||||
|
||||
void save_map_level(OpenGTA::Map & map, size_t level, const char* out_prefix) {
|
||||
SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
|
||||
256, 256, 32,// rmask, gmask, bmask, amask);
|
||||
0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
|
||||
SDL_LockSurface(surface);
|
||||
uint32_t* dst = static_cast<uint32_t*>(surface->pixels);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
for (int j = 0; j < 256; j++) {
|
||||
PHYSFS_uint16 emptycount = map.getNumBlocksAtNew(j,i);
|
||||
if (level < emptycount) {
|
||||
OpenGTA::Map::BlockInfo* bi = map.getBlockAtNew(j, i, level);
|
||||
*dst = map_color[bi->blockType()];
|
||||
}
|
||||
else {
|
||||
*dst = map_color[0];
|
||||
}
|
||||
++dst;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(surface);
|
||||
std::ostringstream ostr;
|
||||
ostr << out_prefix << "_" << level << ".bmp";
|
||||
SDL_SaveBMP(surface, ostr.str().c_str());
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
if (argc < 2) {
|
||||
@ -15,32 +68,16 @@ int main(int argc, char* argv[]) {
|
||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||
|
||||
std::string map_filename(argv[1]);
|
||||
OpenGTA::MainMsgHolder::Instance().load("ENGLISH.FXT");
|
||||
OpenGTA::Map map(map_filename);
|
||||
|
||||
uint32_t green = 0x00dd00ff;
|
||||
uint32_t red = 0xdd0000ff;
|
||||
uint32_t blue = 0x0000ddff;
|
||||
|
||||
uint32_t field = green;
|
||||
uint32_t building = 0xdf9f6fff;
|
||||
uint32_t water = blue;
|
||||
uint32_t road = 0xdadadaff;
|
||||
uint32_t pavement = 0x8a9aa0ff;
|
||||
|
||||
uint32_t map_color[] = {
|
||||
0x000000ff,
|
||||
water,
|
||||
road,
|
||||
pavement,
|
||||
field,
|
||||
building,
|
||||
0xffffffff,
|
||||
0xff0000ff
|
||||
};
|
||||
|
||||
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
for (size_t i = 0; i < 7; i++)
|
||||
save_map_level(map, i, "out");
|
||||
|
||||
#if 0
|
||||
// FIXME: doesn't work right
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
#define rmask 0xff000000
|
||||
@ -102,6 +139,8 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
SDL_UnlockSurface(surface);
|
||||
SDL_SaveBMP(surface, "out.bmp");
|
||||
#endif
|
||||
|
||||
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
|
38
tools/package_binary.sh
Normal file
38
tools/package_binary.sh
Normal file
@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
|
||||
DLL_NAMES_W32=*.dll #"SDL.dll"
|
||||
|
||||
function binary() {
|
||||
local ex_name=$1
|
||||
if [ "$HOST" == "WIN32" ]; then
|
||||
echo $ex_name".exe"
|
||||
echo $DLL_NAMES_W32
|
||||
else
|
||||
echo $ex_name
|
||||
fi
|
||||
}
|
||||
|
||||
function host_txt() {
|
||||
if [ "$HOST" == "WIN32" ]; then
|
||||
unix2dos $@
|
||||
fi
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
function list_files() {
|
||||
binary viewer
|
||||
echo licenses/*
|
||||
host_txt license.txt readme.txt cvs_changelog.txt
|
||||
host_txt doc/using_mods.txt
|
||||
}
|
||||
|
||||
R_DATE=$(cat ogta_version)
|
||||
if [ "$HOST" == "WIN32" ]; then
|
||||
ZIP_FILE_NAME=ogta_sneak-preview-${R_DATE}_win32
|
||||
|
||||
list_files | xargs zip $ZIP_FILE_NAME
|
||||
else
|
||||
TAR_FILE_NAME=ogta_sneak-preview-${R_DATE}_linux.tar.bz2
|
||||
|
||||
list_files | xargs tar jvcf $TAR_FILE_NAME
|
||||
fi
|
25
tools/picasa_ls.sh
Executable file
25
tools/picasa_ls.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
TMP_FILE=/tmp/picasa_lst.$$
|
||||
|
||||
function fetch() {
|
||||
wget -O $TMP_FILE 'http://picasaweb.google.com/data/feed/base/user/under.northern.sky/albumid/5015283825893823185?kind=photo&alt=rss&hl=en_US'
|
||||
}
|
||||
|
||||
function extract() {
|
||||
local _file=$1
|
||||
echo 'cat /rss/channel/item[*]/enclosure|/rss/channel/item[*]/link' \
|
||||
| xmllint --shell $_file | grep http | sed \
|
||||
-e 's|^.*url="||' -e 's|".*$||' -e 's|<\/*link>||g'
|
||||
}
|
||||
|
||||
fetch
|
||||
extract $TMP_FILE | {
|
||||
while read a; do
|
||||
basename $a
|
||||
read b
|
||||
echo $b
|
||||
echo
|
||||
done
|
||||
}
|
||||
rm -f $TMP_FILE
|
34
tools/plot_stats.sh
Executable file
34
tools/plot_stats.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -e stats ]; then
|
||||
echo "start me in the archive dir after creatings 'stats'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sh ../tools/stats_recalc.sh < stats > stats2
|
||||
gnuplot <<EOF
|
||||
set timefmt "%Y-%m-%d"
|
||||
set xdata time
|
||||
set format x "%Y-%m-%d"
|
||||
|
||||
set yr[0:260]
|
||||
set ytics 20
|
||||
set y2tics 0,10,40
|
||||
set grid ytics y2tics
|
||||
|
||||
plot "stats2" using 1:2 title "total size [KB]" with points 1 2
|
||||
replot "stats2" using 1:2 notitle with lines 1
|
||||
replot "stats2" using 1:3 title "files" with points 2 2
|
||||
replot "stats2" using 1:3 notitle with lines 2
|
||||
replot "stats2" using 1:4 title "code lines [K]" with points 7 2
|
||||
replot "stats2" using 1:4 notitle with lines 7
|
||||
|
||||
set output "stats_plot.svg"
|
||||
set terminal svg size 800 400
|
||||
|
||||
replot
|
||||
EOF
|
||||
../tools/replace_in_files.sh "s/black/silver/g" stats_plot.svg
|
||||
inkscape -e stats_plot.png stats_plot.svg
|
||||
|
||||
rm stats2 stats_plot.svg
|
31
tools/projects_stats.sh
Executable file
31
tools/projects_stats.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
infile=$1
|
||||
|
||||
if [ ! -e $infile ]; then
|
||||
echo "gimme a tar.gz"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
archive_size=$(stat -c "%s" $infile)
|
||||
|
||||
tmpdir=/tmp/work_`basename $0`_$$
|
||||
|
||||
mkdir $tmpdir
|
||||
|
||||
bzip2 -cd $infile | ( cd $tmpdir ; tar x)
|
||||
|
||||
cd $tmpdir/ogta || exit 1
|
||||
|
||||
num_files=$(find -type f | wc -l)
|
||||
|
||||
num_code_lines=$(find -name "*.cpp" -o -name "*.c" -o -name "*.hpp" -o -name "*.h" \
|
||||
| xargs wc -l | tail -1 | sed -e 's/^ *//' -e 's/ total//')
|
||||
|
||||
filename=$(basename $infile)
|
||||
filename=${filename%%.tar.bz2}
|
||||
filename=${filename##ogta_src_}
|
||||
|
||||
echo "$filename $archive_size $num_files $num_code_lines"
|
||||
|
||||
rm -rf $tmpdir
|
18
tools/raw_images.m4
Normal file
18
tools/raw_images.m4
Normal file
@ -0,0 +1,18 @@
|
||||
define(`FIND_AT', `(iname.find("$1") == $2)')dnl
|
||||
define(`CONDITION', `if ($1) {
|
||||
$2
|
||||
}')dnl
|
||||
define(`RESULT', `width = $1; height = $2;')dnl
|
||||
dnl
|
||||
CONDITION(`FIND_AT(`CUT', 0) && FIND_AT(`.RA', 4)', `RESULT(640, 480)')
|
||||
CONDITION(`FIND_AT(`F_BMG.RA', 0)', `RESULT(100, 50)')
|
||||
CONDITION(`FIND_AT(`F_DMA.RA', 0)', `RESULT(78, 109)')
|
||||
CONDITION(`FIND_AT(`F_LOGO', 0) && FIND_AT(`.RA', 7)', `RESULT(640, 168)')
|
||||
CONDITION(`FIND_AT(`F_LOWER', 0) && FIND_AT(`.RA', 8)', `RESULT(640, 312)')
|
||||
CONDITION(`FIND_AT(`F_PLAYN.RA', 0)', `RESULT(180, 50)')
|
||||
CONDITION(`FIND_AT(`F_PLAY', 0) && FIND_AT(`.RA', 7)', `RESULT(102, 141)')
|
||||
CONDITION(`FIND_AT(`F_UPPER.RA', 0)', `RESULT(640, 168)')
|
||||
dnl
|
||||
dnl see: http://membres.lycos.fr/dolmen/gta/raw.html
|
||||
dnl flag2.raw 20x200
|
||||
dnl joy.raw 19x18
|
6
tools/stats_recalc.sh
Executable file
6
tools/stats_recalc.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
while read a b c d; do
|
||||
b=$(echo "$b / 1024" | bc -l)
|
||||
d=$(echo "$d / 1000" | bc -l)
|
||||
echo "$a $b $c $d"
|
||||
done
|
@ -40,6 +40,12 @@ namespace Util {
|
||||
return 360.0f + res;
|
||||
return res;
|
||||
}
|
||||
float xz_turn_angle(const Vector3D & from, const Vector3D & to) {
|
||||
Vector3D rel_to(to);
|
||||
rel_to = rel_to - from;
|
||||
double res = atan(rel_to.x / rel_to.z) * 180.0f / M_PI;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CellIterator::isValid() const {
|
||||
if (x < 0 || x > 255)
|
||||
@ -51,7 +57,7 @@ namespace Util {
|
||||
return (z < mapRef.getNumBlocksAtNew(x, y));
|
||||
}
|
||||
|
||||
OpenGTA::Map::BlockInfo & CellIterator::getBlock() {
|
||||
OpenGTA::Map::BlockInfo & CellIterator::getBlock() const {
|
||||
assert(isValid());
|
||||
return *mapRef.getBlockAtNew(x, y, z);
|
||||
}
|
||||
@ -61,4 +67,76 @@ namespace Util {
|
||||
return (IABS(x - o.x) + IABS(y - o.y) + IABS(z - o.z));
|
||||
}
|
||||
|
||||
bool CellIterator::isBlockType(uint8_t t) const {
|
||||
if (!isValid())
|
||||
return false;
|
||||
return (getBlock().blockType() == t);
|
||||
}
|
||||
|
||||
std::pair<bool, CellIterator> CellIterator::findTypeInCol(uint8_t t) const {
|
||||
if (isBlockType(t))
|
||||
return std::make_pair<bool, CellIterator>(true, *this);
|
||||
CellIterator below = down();
|
||||
while (below.isValid()) {
|
||||
if (below.isBlockType(t))
|
||||
return std::make_pair<bool, CellIterator>(true, below);
|
||||
below = below.down();
|
||||
}
|
||||
CellIterator above = up();
|
||||
while (above.isValid()) {
|
||||
if (above.isBlockType(t))
|
||||
return std::make_pair<bool, CellIterator>(true, above);
|
||||
above = above.up();
|
||||
}
|
||||
return std::make_pair<bool, CellIterator>(false, *this);
|
||||
}
|
||||
|
||||
std::pair<bool, CellIterator> CellIterator::findNeighbourWithType(
|
||||
uint8_t t, float angle_hint) {
|
||||
assert(isValid());
|
||||
|
||||
if (angle_hint >= 315 || angle_hint < 45) {
|
||||
std::pair<bool, CellIterator> p = top().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
if (angle_hint >= 0 || angle_hint < 90) {
|
||||
std::pair<bool, CellIterator> p = top().right().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
if (angle_hint >= 45 && angle_hint < 135) {
|
||||
std::pair<bool, CellIterator> p = right().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
if (angle_hint >= 90 && angle_hint < 180) {
|
||||
std::pair<bool, CellIterator> p = right().bottom().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
if (angle_hint >= 135 && angle_hint < 225) {
|
||||
std::pair<bool, CellIterator> p = bottom().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
if (angle_hint >= 180 && angle_hint < 270) {
|
||||
std::pair<bool, CellIterator> p = left().bottom().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
if (angle_hint >= 225 && angle_hint < 315) {
|
||||
std::pair<bool, CellIterator> p = left().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
if (angle_hint >= 270 && angle_hint < 360) {
|
||||
std::pair<bool, CellIterator> p = top().left().findTypeInCol(t);
|
||||
// if (p.first) INFO << p.second.x << " " << p.second.y << " " << p.second.z << std::endl;
|
||||
if (p.first) return p;
|
||||
}
|
||||
return std::make_pair<bool, CellIterator>(false, *this);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
namespace Util {
|
||||
float distance(const Vector3D & p1, const Vector3D & p2);
|
||||
float xz_angle(const Vector3D & from, const Vector3D & to);
|
||||
float xz_turn_angle(const Vector3D & from, const Vector3D & to);
|
||||
|
||||
class CellIterator {
|
||||
public:
|
||||
@ -89,8 +90,11 @@ namespace Util {
|
||||
p.z -= 1;
|
||||
return p;
|
||||
}
|
||||
bool isBlockType(uint8_t t) const;
|
||||
std::pair<bool, CellIterator> findTypeInCol(uint8_t t) const;
|
||||
std::pair<bool, CellIterator> findNeighbourWithType(uint8_t t, float angle_hint);
|
||||
int x, y, z;
|
||||
OpenGTA::Map::BlockInfo & getBlock();
|
||||
OpenGTA::Map::BlockInfo & getBlock() const;
|
||||
private:
|
||||
OpenGTA::Map & mapRef;
|
||||
};
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "m_exceptions.h"
|
||||
#include "file_helper.h"
|
||||
#include "buffercache.h"
|
||||
#include "log.h"
|
||||
|
||||
#ifndef OGTA_DEFAULT_DATA_PATH
|
||||
#define OGTA_DEFAULT_DATA_PATH "gtadata.zip"
|
||||
@ -117,4 +118,24 @@ namespace Util {
|
||||
PHYSFS_close(fd);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const std::string FileHelper::lang2MsgFilename(const char *l) {
|
||||
assert(l);
|
||||
std::string lang(l);
|
||||
if (lang.size() > 2)
|
||||
lang = lang.substr(0, 2);
|
||||
std::transform(lang.begin(), lang.end(), lang.begin(), tolower);
|
||||
if (lang == "en")
|
||||
return std::string("ENGLISH.FXT");
|
||||
else if (lang == "de")
|
||||
return std::string("GERMAN.FXT");
|
||||
else if (lang == "fr")
|
||||
return std::string("FRENCH.FXT");
|
||||
else if (lang == "it")
|
||||
return std::string("ITALIAN.FXT");
|
||||
|
||||
WARN << "Unknown language: " << l << " - falling back to english"
|
||||
<< std::endl;
|
||||
return std::string("ENGLISH.FXT");
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ namespace Util {
|
||||
bool existsInVFS(const std::string & file) const;
|
||||
PHYSFS_file* openReadVFS(const std::string & file) const;
|
||||
unsigned char* bufferFromVFS(PHYSFS_file*) const;
|
||||
static const std::string lang2MsgFilename(const char* l);
|
||||
private:
|
||||
std::string baseDataPath;
|
||||
std::string modDataPath;
|
||||
|
559
util/gui.cpp
Normal file
559
util/gui.cpp
Normal file
@ -0,0 +1,559 @@
|
||||
#include "gui.h"
|
||||
#include "m_exceptions.h"
|
||||
#include "dataholder.h"
|
||||
#include "gl_spritecache.h"
|
||||
#include "gl_screen.h"
|
||||
#ifdef WITH_LUA
|
||||
#include "lua_vm.h"
|
||||
#endif
|
||||
#include <sstream>
|
||||
#include "localplayer.h"
|
||||
|
||||
extern float screen_gamma;
|
||||
namespace GUI {
|
||||
Object::Object(const SDL_Rect & r) :
|
||||
id(0), rect(), color(), borderColor(), drawBorder(false),
|
||||
manager(ManagerHolder::Instance()) {
|
||||
copyRect(r);
|
||||
color.r = 255; color.g = 255; color.b = 255; color.unused = 255;
|
||||
}
|
||||
Object::Object(const size_t Id, const SDL_Rect & r) :
|
||||
id(Id), rect(), color(), borderColor(), drawBorder(false),
|
||||
manager(ManagerHolder::Instance()) {
|
||||
copyRect(r);
|
||||
color.r = 255; color.g = 255; color.b = 255; color.unused = 255;
|
||||
}
|
||||
Object::Object(const size_t Id, const SDL_Rect & r, const SDL_Color & c) :
|
||||
id(Id), rect(), color(), borderColor(), drawBorder(false),
|
||||
manager(ManagerHolder::Instance()) {
|
||||
copyRect(r);
|
||||
copyColor(c);
|
||||
}
|
||||
void Object::draw() {
|
||||
glEnable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(rect.x, rect.y);
|
||||
glVertex2i(rect.x + rect.w, rect.y);
|
||||
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||
glVertex2i(rect.x, rect.y + rect.h);
|
||||
glEnd();
|
||||
if (drawBorder)
|
||||
draw_border();
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
void Object::draw_border() {
|
||||
glColor4ub(borderColor.r, borderColor.g, borderColor.b,
|
||||
borderColor.unused);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex2i(rect.x, rect.y);
|
||||
glVertex2i(rect.x + rect.w, rect.y);
|
||||
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||
glVertex2i(rect.x, rect.y + rect.h);
|
||||
glEnd();
|
||||
}
|
||||
void Object::copyRect(const SDL_Rect & src) {
|
||||
rect.x = src.x;
|
||||
rect.y = src.y;
|
||||
rect.w = src.w;
|
||||
rect.h = src.h;
|
||||
}
|
||||
void Object::copyColor(const SDL_Color & src) {
|
||||
color.r = src.r;
|
||||
color.g = src.g;
|
||||
color.b = src.b;
|
||||
color.unused = src.unused;
|
||||
}
|
||||
void TexturedObject::draw() {
|
||||
if (texId == 0)
|
||||
return;
|
||||
const OpenGL::PagedTexture & tex = manager.getCachedImage(texId);
|
||||
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, tex.inPage);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(tex.coords[0].u, tex.coords[1].v);
|
||||
glVertex2i(rect.x, rect.y);
|
||||
glTexCoord2f(tex.coords[1].u, tex.coords[1].v);
|
||||
glVertex2i(rect.x + rect.w, rect.y);
|
||||
glTexCoord2f(tex.coords[1].u, tex.coords[0].v);
|
||||
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||
glTexCoord2f(tex.coords[0].u, tex.coords[0].v);
|
||||
glVertex2i(rect.x, rect.y + rect.h);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (drawBorder)
|
||||
draw_border();
|
||||
}
|
||||
|
||||
void AnimatedTextureObject::draw() {
|
||||
if (!animation)
|
||||
animation = manager.findAnimation(animId);
|
||||
|
||||
assert(animation);
|
||||
size_t texId = animation->getCurrentFrame();
|
||||
const OpenGL::PagedTexture & tex = manager.getCachedImage(texId);
|
||||
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, tex.inPage);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(tex.coords[0].u, tex.coords[1].v);
|
||||
glVertex2i(rect.x, rect.y);
|
||||
glTexCoord2f(tex.coords[1].u, tex.coords[1].v);
|
||||
glVertex2i(rect.x + rect.w, rect.y);
|
||||
glTexCoord2f(tex.coords[1].u, tex.coords[0].v);
|
||||
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||
glTexCoord2f(tex.coords[0].u, tex.coords[0].v);
|
||||
glVertex2i(rect.x, rect.y + rect.h);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (drawBorder)
|
||||
draw_border();
|
||||
}
|
||||
|
||||
void Label::draw() {
|
||||
glPushMatrix();
|
||||
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
if (align == 0) {
|
||||
glTranslatef(rect.x, rect.y, 0);
|
||||
rect.w = uint16_t(font->drawString(text));
|
||||
}
|
||||
else if (align == 1) {
|
||||
glTranslatef(rect.x, rect.y, 0);
|
||||
rect.w = uint16_t(font->drawString_r2l(text));
|
||||
}
|
||||
rect.h = font->getHeight();
|
||||
glPopMatrix();
|
||||
/*
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2i(rect.x, rect.y);
|
||||
glVertex2i(rect.x + rect.w, rect.y);
|
||||
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||
glVertex2i(rect.x, rect.y + rect.h);
|
||||
glVertex2i(rect.x, rect.y);
|
||||
glEnd();
|
||||
*/
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (drawBorder)
|
||||
draw_border();
|
||||
}
|
||||
|
||||
void Pager::draw() {
|
||||
|
||||
const OpenGL::PagedTexture & tex = manager.getCachedImage(texId);
|
||||
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, tex.inPage);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(tex.coords[0].u, tex.coords[1].v);
|
||||
glVertex2i(rect.x, rect.y);
|
||||
glTexCoord2f(tex.coords[1].u, tex.coords[1].v);
|
||||
glVertex2i(rect.x + rect.w, rect.y);
|
||||
glTexCoord2f(tex.coords[1].u, tex.coords[0].v);
|
||||
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||
glTexCoord2f(tex.coords[0].u, tex.coords[0].v);
|
||||
glVertex2i(rect.x, rect.y + rect.h);
|
||||
glEnd();
|
||||
glScissor(rect.x, rect.y, rect.w, rect.h);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
glPushMatrix();
|
||||
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||
glTranslatef(rect.x+offset, rect.y+4, 0);
|
||||
int slen = (int)font->drawString("test - hello world, this is a really long message. it will not end. never... or maybe sometime, but not yet. The end.");
|
||||
if (slen + offset < -10) {
|
||||
color.unused = 0;
|
||||
manager.remove(this);
|
||||
}
|
||||
INFO << slen <<" " << offset << std::endl;
|
||||
glPopMatrix();
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (drawBorder)
|
||||
draw_border();
|
||||
|
||||
}
|
||||
|
||||
void Pager::update(Uint32 ticks) {
|
||||
offset -= 1;
|
||||
|
||||
//if (offset < -50)
|
||||
// color.unused = 0;
|
||||
}
|
||||
|
||||
void Manager::draw() {
|
||||
GuiObjectListMap::iterator layer_it = guiLayers.begin();
|
||||
|
||||
while (layer_it != guiLayers.end()) {
|
||||
GuiObjectList & inThisLayer = layer_it->second;
|
||||
for (GuiObjectList::iterator obj_it = inThisLayer.begin();
|
||||
obj_it != inThisLayer.end(); ++obj_it) {
|
||||
Object * obj = *obj_it;
|
||||
obj->draw();
|
||||
}
|
||||
++layer_it;
|
||||
}
|
||||
glColor4f(1, 1, 1, 1);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
Manager::~Manager() {
|
||||
clearObjects();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void Manager::clearObjects() {
|
||||
INFO << "clearing gui objects" << std::endl;
|
||||
GuiObjectListMap::iterator layer_it = guiLayers.begin();
|
||||
while (layer_it != guiLayers.end()) {
|
||||
GuiObjectList & list = layer_it->second;
|
||||
for (GuiObjectList::iterator i = list.begin(); i != list.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
list.clear();
|
||||
++layer_it;
|
||||
}
|
||||
guiLayers.clear();
|
||||
}
|
||||
|
||||
void Manager::clearCache() {
|
||||
INFO << "clearing gui texture cache" << std::endl;
|
||||
for (GuiTextureCache::iterator i = texCache.begin(); i != texCache.end(); ++i) {
|
||||
OpenGL::PagedTexture & p = i->second;
|
||||
glDeleteTextures(1, &p.inPage);
|
||||
}
|
||||
texCache.clear();
|
||||
for (AnimationMap::iterator i = guiAnimations.begin(); i != guiAnimations.end(); ++i) {
|
||||
delete i->second;
|
||||
}
|
||||
guiAnimations.clear();
|
||||
}
|
||||
|
||||
const OpenGL::PagedTexture & Manager::getCachedImage(size_t Id) {
|
||||
GuiTextureCache::iterator i = findByCacheId(Id);
|
||||
if (i == texCache.end()) {
|
||||
std::ostringstream o;
|
||||
o << "cached texture id " << int(Id);
|
||||
throw E_UNKNOWNKEY(o.str());
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
Manager::GuiTextureCache::iterator Manager::findByCacheId(const size_t & Id) {
|
||||
return texCache.find(Id);
|
||||
}
|
||||
|
||||
Manager::GuiObjectListMap::iterator Manager::findLayer(uint8_t l) {
|
||||
return guiLayers.find(l);
|
||||
}
|
||||
|
||||
void Manager::cacheImageRAW(const std::string & file, size_t k) {
|
||||
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(k, ImageUtil::loadImageRAW(file)));
|
||||
}
|
||||
|
||||
void Manager::cacheImageRAT(const std::string & file, const std::string & palette, size_t k) {
|
||||
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(k,
|
||||
ImageUtil::loadImageRATWithPalette(file, palette)));
|
||||
}
|
||||
|
||||
ImageUtil::WidthHeightPair Manager::cacheStyleArrowSprite(const size_t id, int remap) {
|
||||
OpenGTA::GraphicsBase & graphics = OpenGTA::StyleHolder::Instance().get();
|
||||
PHYSFS_uint16 t = graphics.spriteNumbers.reIndex(id, OpenGTA::GraphicsBase::SpriteNumbers::ARROW);
|
||||
OpenGTA::GraphicsBase::SpriteInfo * info = graphics.getSprite(t);
|
||||
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(
|
||||
id, OpenGL::SpriteCacheHolder::Instance().createSprite(size_t(t), remap, 0, info)
|
||||
));
|
||||
return ImageUtil::WidthHeightPair(info->w, info->h);
|
||||
}
|
||||
|
||||
#ifdef WITH_SDL_IMAGE
|
||||
void Manager::cacheImageSDL(const std::string & file, size_t k) {
|
||||
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(k,
|
||||
ImageUtil::loadImageSDL(file)));
|
||||
}
|
||||
#endif
|
||||
|
||||
void Manager::add(Object * obj, uint8_t onLevel) {
|
||||
GuiObjectListMap::iterator l = findLayer(onLevel);
|
||||
if (l == guiLayers.end()) {
|
||||
GuiObjectList list;
|
||||
list.push_back(obj);
|
||||
guiLayers.insert(std::make_pair<uint8_t, GuiObjectList>(onLevel, list));
|
||||
return;
|
||||
}
|
||||
GuiObjectList & list = l->second;
|
||||
list.push_back(obj);
|
||||
}
|
||||
|
||||
void Manager::remove(Object * obj) {
|
||||
for (GuiObjectListMap::iterator l = guiLayers.begin(); l != guiLayers.end(); ++l) {
|
||||
GuiObjectList & list = l->second;
|
||||
for (GuiObjectList::iterator m = list.begin(); m != list.end(); ++m) {
|
||||
Object * o = *m;
|
||||
if (o == obj) {
|
||||
delete o;
|
||||
list.erase(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw E_UNKNOWNKEY("not a managed object-ptr");
|
||||
}
|
||||
|
||||
Object* Manager::findObject(const size_t id) {
|
||||
for (GuiObjectListMap::iterator l = guiLayers.begin(); l != guiLayers.end(); ++l) {
|
||||
GuiObjectList & list = l->second;
|
||||
for (GuiObjectList::iterator m = list.begin(); m != list.end(); ++m) {
|
||||
Object * o = *m;
|
||||
if (o->id == id)
|
||||
return o;
|
||||
}
|
||||
}
|
||||
std::ostringstream o;
|
||||
o << "object by id " << int(id);
|
||||
throw E_UNKNOWNKEY(o.str());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Manager::removeById(const size_t id) {
|
||||
Object * o = findObject(id);
|
||||
if (o)
|
||||
remove(o);
|
||||
//else
|
||||
// ERROR << "failed to find object " << id << " - cannot remove it" << std::endl;
|
||||
}
|
||||
|
||||
bool Manager::isInside(Object & obj, Uint16 x, Uint16 y) const {
|
||||
if ((obj.rect.x <= x) && (x <= obj.rect.x + obj.rect.w) &&
|
||||
(obj.rect.y <= y) && (y <= obj.rect.y + obj.rect.h))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
void Manager::receive(SDL_MouseButtonEvent & mb_event) {
|
||||
Uint32 sh = OpenGL::ScreenHolder::Instance().getHeight();
|
||||
GuiObjectListMap::reverse_iterator l = guiLayers.rbegin();
|
||||
while (l != guiLayers.rend()) {
|
||||
GuiObjectList & list = l->second;
|
||||
for (GuiObjectList::iterator i = list.begin(); i != list.end(); ++i) {
|
||||
Object * obj = *i;
|
||||
if (isInside(*obj, mb_event.x, sh - mb_event.y)) {
|
||||
// std::cout << "mouse inside obj id: " << obj->id << " at " << mb_event.x << "," << mb_event.y << std::endl;
|
||||
obj->receive(mb_event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
++l;
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::update(uint32_t nowticks) {
|
||||
for (AnimationMap::iterator i = guiAnimations.begin(); i != guiAnimations.end(); ++i) {
|
||||
i->second->update(nowticks);
|
||||
}
|
||||
GuiObjectListMap::iterator layer_it = guiLayers.begin();
|
||||
while (layer_it != guiLayers.end()) {
|
||||
GuiObjectList & inThisLayer = layer_it->second;
|
||||
for (GuiObjectList::iterator obj_it = inThisLayer.begin();
|
||||
obj_it != inThisLayer.end(); ++obj_it) {
|
||||
Object * obj = *obj_it;
|
||||
obj->update(nowticks);
|
||||
}
|
||||
++layer_it;
|
||||
}
|
||||
}
|
||||
|
||||
Animation* Manager::findAnimation(uint16_t id) {
|
||||
AnimationMap::iterator i = guiAnimations.find(id);
|
||||
return i->second;
|
||||
}
|
||||
void Manager::createAnimation(const std::vector<uint16_t> & indices, uint16_t fps, size_t k) {
|
||||
Animation * anim = new Animation(indices, fps);
|
||||
guiAnimations.insert(std::make_pair<size_t, Animation*>(k, anim));
|
||||
anim->set(Util::Animation::PLAY_FORWARD, Util::Animation::LOOP);
|
||||
}
|
||||
|
||||
uint16_t Animation::getCurrentFrame() {
|
||||
return indices[getCurrentFrameNumber()];
|
||||
}
|
||||
|
||||
const int WEAPON_DISPLAY_ID = 100;
|
||||
|
||||
const SDL_Rect sdl_rect(size_t a, size_t b, size_t c, size_t d) {
|
||||
SDL_Rect rect;
|
||||
rect.x = a;
|
||||
rect.y = b;
|
||||
rect.w = c;
|
||||
rect.h = d;
|
||||
return rect;
|
||||
}
|
||||
|
||||
WeaponDisplay::WeaponDisplay(const SDL_Rect & r) : Object(WEAPON_DISPLAY_ID, r),
|
||||
img(sdl_rect(r.x+2, r.y+2, r.w - 4, r.h - 4), 0),
|
||||
label(sdl_rect(r.x+2, r.y+r.h, r.w - 4, r.h - 4), "", "F_MTEXT.FON", 1) {
|
||||
}
|
||||
|
||||
void WeaponDisplay::draw() {
|
||||
img.draw();
|
||||
label.draw();
|
||||
}
|
||||
|
||||
size_t WeaponDisplay::getWeaponIdx(const size_t wt) {
|
||||
if (wt == 0)
|
||||
return 0;
|
||||
if (wt < 5)
|
||||
return 1000 + wt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WeaponDisplay::setWeapon(const size_t wt) {
|
||||
img.texId = getWeaponIdx(wt);
|
||||
try {
|
||||
manager.getCachedImage(img.texId);
|
||||
}
|
||||
catch (const Util::UnknownKey & ek) {
|
||||
WARN << "GUI image for weapon " << wt << " not loaded - retrying" << std::endl;
|
||||
manager.cacheStyleArrowSprite(img.texId, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollBar::draw() {
|
||||
Object::draw();
|
||||
glColor3ub(innerColor.r, innerColor.g, innerColor.b);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(rect.x+2, rect.y+2);
|
||||
glVertex2i(rect.x + int(rect.w * value) -2, rect.y+2);
|
||||
glVertex2i(rect.x + int(rect.w * value) -2, rect.y + rect.h-2);
|
||||
glVertex2i(rect.x+2, rect.y + rect.h-2);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void ScrollBar::receive(SDL_MouseButtonEvent & mb_event) {
|
||||
value = (mb_event.x - rect.x) / float(rect.w - 4);
|
||||
INFO << value << std::endl;
|
||||
if (changeCB)
|
||||
changeCB(value * 2);
|
||||
else
|
||||
WARN << "No callback function set - I ain't seen nothing" <<
|
||||
std::endl;
|
||||
/*
|
||||
SDL_SetGamma(value * 2, value * 2, value * 2);
|
||||
Object * o = ManagerHolder::Instance().findObject(101);
|
||||
if (o) {
|
||||
std::ostringstream os;
|
||||
os << "Gamma: " << value * 2;
|
||||
static_cast<Label*>(o)->text = os.str();
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
void screen_gamma_callback(float v) {
|
||||
screen_gamma = v;
|
||||
SDL_SetGamma(v, v, v);
|
||||
#ifdef WITH_LUA
|
||||
OpenGTA::Script::LuaVM & vm = OpenGTA::Script::LuaVMHolder::Instance();
|
||||
lua_State *L = vm.getInternalState();
|
||||
int top = lua_gettop(L);
|
||||
lua_getglobal(L, "config");
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "config");
|
||||
}
|
||||
uint8_t sf = OpenGTA::StyleHolder::Instance().get().getFormat();
|
||||
if (sf)
|
||||
vm.setFloat("screen_gamma_g24", v);
|
||||
else
|
||||
vm.setFloat("screen_gamma_gry", v);
|
||||
lua_settop(L, top);
|
||||
#endif
|
||||
Object * o = ManagerHolder::Instance().findObject(GAMMA_LABEL_ID);
|
||||
if (o) {
|
||||
std::ostringstream os;
|
||||
os << "Gamma: " << v;
|
||||
static_cast<Label*>(o)->text = os.str();
|
||||
}
|
||||
/*
|
||||
Object * o2 = ManagerHolder::Instance().findObject(1001);
|
||||
if (o2) {
|
||||
static_cast<ImageStatusDisplay*>(o2)->number = screen_gamma * 3;
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
AnimStatusDisplay* wantedLevel = NULL;
|
||||
Label* cashLabel = NULL;
|
||||
|
||||
void create_ingame_gui(bool is32bit) {
|
||||
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||
GUI::Manager & gm = ManagerHolder::Instance();
|
||||
assert(!wantedLevel);
|
||||
{
|
||||
SDL_Rect r;
|
||||
r.h = 32;
|
||||
r.x = screen.getWidth() / 2 - 50;
|
||||
r.y = screen.getHeight() - r.h;
|
||||
r.w = 100;
|
||||
SDL_Rect rs;
|
||||
rs.x = rs.y = 0;
|
||||
rs.w = rs.h = 16;
|
||||
gm.cacheStyleArrowSprite(16, -1);
|
||||
gm.cacheStyleArrowSprite(17, -1);
|
||||
std::vector<uint16_t> anim2frames(2);
|
||||
anim2frames[0] = 16;
|
||||
anim2frames[1] = 17;
|
||||
gm.createAnimation(anim2frames, 10, 2);
|
||||
wantedLevel = new AnimStatusDisplay(WANTED_LEVEL_ID, r, rs, 2);
|
||||
/*
|
||||
wantedLevel->borderColor.r = wantedLevel->borderColor.g = wantedLevel->borderColor.b = wantedLevel->borderColor.unused = 255;
|
||||
wantedLevel->drawBorder = 1;
|
||||
*/
|
||||
gm.add(wantedLevel, 50);
|
||||
}
|
||||
assert(!cashLabel);
|
||||
{
|
||||
SDL_Rect r;
|
||||
r.x = screen.getWidth() - 5;
|
||||
r.y = screen.getHeight() - 30;
|
||||
cashLabel = new Label(GUI::CASH_ID, r, "0", "F_MTEXT.FON", 1);
|
||||
cashLabel->align = 1;
|
||||
gm.add(cashLabel, 50);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void update_ingame_gui_values() {
|
||||
OpenGTA::PlayerController & pc = OpenGTA::LocalPlayer::Instance();
|
||||
|
||||
if (wantedLevel)
|
||||
wantedLevel->number = pc.getWantedLevel();
|
||||
|
||||
if (cashLabel) {
|
||||
std::ostringstream os;
|
||||
os << pc.getCash();
|
||||
cashLabel->text = os.str();
|
||||
}
|
||||
}
|
||||
|
||||
void remove_ingame_gui() {
|
||||
GUI::Manager & gm = ManagerHolder::Instance();
|
||||
|
||||
if (wantedLevel)
|
||||
gm.remove(wantedLevel);
|
||||
wantedLevel = NULL;
|
||||
|
||||
if (cashLabel)
|
||||
gm.remove(cashLabel);
|
||||
cashLabel = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
93
util/gui.h
93
util/gui.h
@ -36,6 +36,18 @@ namespace GUI {
|
||||
struct Object;
|
||||
class Animation;
|
||||
|
||||
/** Wrapper around GUI elements.
|
||||
*
|
||||
* Contains a number of lists of objects; mouse click events can be delegated
|
||||
* to any element. Elements are placed into "layers"; drawing is done from
|
||||
* low to high (0 .. 255), clicked-inside is tested high to low (255 ... 0).
|
||||
*
|
||||
* Objects _should_ have a unique id (removeById only finds the first match),
|
||||
* but this is neither ensured nor required.
|
||||
*
|
||||
* Finally there are helper functions (which are used by derived objects) to
|
||||
* load/access images/animations.
|
||||
*/
|
||||
class Manager {
|
||||
public:
|
||||
Manager() {}
|
||||
@ -47,11 +59,13 @@ namespace GUI {
|
||||
void draw();
|
||||
void clearObjects();
|
||||
void clearCache();
|
||||
void cacheImageRAW(const std::string & file, size_t asId);
|
||||
void cacheImageRAT(const std::string & file, const std::string & palette, size_t asId);
|
||||
void cacheImageSDL(const std::string & file, size_t asId);
|
||||
void cacheImageRAW(const std::string & file, size_t id);
|
||||
void cacheImageRAT(const std::string & file, const std::string & palette, size_t id);
|
||||
#ifdef WITH_SDL_IMAGE
|
||||
void cacheImageSDL(const std::string & file, size_t id);
|
||||
#endif
|
||||
ImageUtil::WidthHeightPair cacheStyleArrowSprite(const size_t id, int remap);
|
||||
const OpenGL::PagedTexture & getCachedImage(size_t Id);
|
||||
const OpenGL::PagedTexture & getCachedImage(size_t id);
|
||||
void receive(SDL_MouseButtonEvent & mb_event);
|
||||
Animation* findAnimation(uint16_t id);
|
||||
void createAnimation(const std::vector<uint16_t> & indices, uint16_t fps, size_t asAnimId);
|
||||
@ -83,6 +97,8 @@ namespace GUI {
|
||||
uint16_t getCurrentFrame();
|
||||
};
|
||||
|
||||
/** Base-object - Can be used to draw coloured area & border.
|
||||
*/
|
||||
struct Object {
|
||||
Object(const SDL_Rect & r);
|
||||
Object(const size_t Id, const SDL_Rect & r);
|
||||
@ -91,10 +107,14 @@ namespace GUI {
|
||||
size_t id;
|
||||
SDL_Rect rect;
|
||||
SDL_Color color;
|
||||
SDL_Color borderColor;
|
||||
bool drawBorder;
|
||||
void copyRect(const SDL_Rect & src);
|
||||
void copyColor(const SDL_Color & src);
|
||||
virtual void draw();
|
||||
virtual void update(Uint32 ticks) {}
|
||||
virtual void receive(SDL_MouseButtonEvent & mb_event) {}
|
||||
void draw_border();
|
||||
Manager & manager;
|
||||
};
|
||||
|
||||
@ -133,9 +153,11 @@ namespace GUI {
|
||||
const std::string & fontFile, const size_t fontScale) : Object(Id, r), text(s) {
|
||||
OpenGL::DrawableFont & fnt = OpenGTA::FontCacheHolder::Instance().getFont(fontFile, fontScale);
|
||||
font = &fnt;
|
||||
align = 0;
|
||||
}
|
||||
OpenGL::DrawableFont * font;
|
||||
std::string text;
|
||||
uint8_t align;
|
||||
void draw();
|
||||
};
|
||||
|
||||
@ -154,5 +176,68 @@ namespace GUI {
|
||||
std::string lastMsg;
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct WeaponDisplay : public Object {
|
||||
public:
|
||||
WeaponDisplay(const SDL_Rect & r);
|
||||
void setWeapon(const size_t wt);
|
||||
void draw();
|
||||
private:
|
||||
size_t getWeaponIdx(const size_t wt);
|
||||
TexturedObject img;
|
||||
Label label;
|
||||
};
|
||||
|
||||
struct ScrollBar : public Object {
|
||||
ScrollBar(const size_t Id, const SDL_Rect & r) : Object(Id, r) {
|
||||
value = 0.5f;
|
||||
}
|
||||
void draw();
|
||||
void receive(SDL_MouseButtonEvent & mb_event);
|
||||
SDL_Color innerColor;
|
||||
float value;
|
||||
typedef Loki::Functor<void, LOKI_TYPELIST_1(float)> SC_Functor;
|
||||
SC_Functor changeCB;
|
||||
};
|
||||
|
||||
template <class Child_T, typename V>
|
||||
struct Number2Status : public Object {
|
||||
Number2Status(const size_t Id, const SDL_Rect & r, const SDL_Rect & ir, const size_t vId) :
|
||||
Object(Id, r),
|
||||
item(r, vId),
|
||||
number(0), align(0),
|
||||
innerRect(ir) {}
|
||||
Child_T item;
|
||||
V number;
|
||||
uint8_t align;
|
||||
SDL_Rect innerRect;
|
||||
void draw() {
|
||||
innerRect.x = (align == 0 ? rect.x : rect.x + rect.w - innerRect.w);
|
||||
innerRect.y = rect.y;
|
||||
memcpy(&item.rect, &innerRect, sizeof(rect));
|
||||
for (V k = 0; k < number; k++) {
|
||||
item.draw();
|
||||
item.rect.x += (align == 0 ? item.rect.w + 1 : -item.rect.w - 1);
|
||||
}
|
||||
if (drawBorder)
|
||||
draw_border();
|
||||
}
|
||||
};
|
||||
|
||||
typedef Number2Status<TexturedObject, int32_t> ImageStatusDisplay;
|
||||
typedef Number2Status<AnimatedTextureObject, int32_t> AnimStatusDisplay;
|
||||
|
||||
void screen_gamma_callback(float v);
|
||||
|
||||
void create_ingame_gui(bool is32bit);
|
||||
void update_ingame_gui_values();
|
||||
void remove_ingame_gui();
|
||||
|
||||
static const uint32_t GAMMA_SCROLLBAR_ID = 100;
|
||||
static const uint32_t GAMMA_LABEL_ID = 101;
|
||||
|
||||
static const uint32_t CASH_ID = 200;
|
||||
static const uint32_t WANTED_LEVEL_ID = 201;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
@ -28,6 +28,9 @@
|
||||
#include "log.h"
|
||||
#include "cistring.h"
|
||||
#include "opengta.h"
|
||||
#include "physfsrwops.h"
|
||||
#include "SDL_image.h"
|
||||
#include "m_exceptions.h"
|
||||
|
||||
namespace ImageUtil {
|
||||
using OpenGL::PagedTexture;
|
||||
@ -88,6 +91,7 @@ using OpenGL::PagedTexture;
|
||||
if (whp.first == 0 || whp.second == 0) {
|
||||
PHYSFS_close(fd);
|
||||
WARN << "aborting image load" << std::endl;
|
||||
throw E_UNKNOWNKEY(name + " - RAW file size unknown");
|
||||
}
|
||||
|
||||
Util::BufferCache::LockedBuffer lbuf(nbytes);
|
||||
@ -115,6 +119,7 @@ using OpenGL::PagedTexture;
|
||||
if (whp.first == 0 || whp.second == 0) {
|
||||
PHYSFS_close(fd);
|
||||
WARN << "aborting image load" << std::endl;
|
||||
throw E_UNKNOWNKEY(name + " - RAT file size unknown");
|
||||
}
|
||||
Util::BufferCache::LockedBuffer lb1(nbytes);
|
||||
PHYSFS_read(fd, lb1(), 1, nbytes);
|
||||
@ -131,20 +136,53 @@ using OpenGL::PagedTexture;
|
||||
return createEmbeddedTexture(whp.first, whp.second, false, lb2());
|
||||
}
|
||||
|
||||
#ifdef WITH_SDL_IMAGE
|
||||
OpenGL::PagedTexture loadImageSDL(const std::string & name) {
|
||||
SDL_RWops * rwops = PHYSFSRWOPS_openRead(name.c_str());
|
||||
SDL_Surface *surface = IMG_Load_RW(rwops, 1);
|
||||
assert(surface);
|
||||
|
||||
NextPowerOfTwo npot(surface->w, surface->h);
|
||||
uint16_t bpp = surface->format->BytesPerPixel;
|
||||
|
||||
uint8_t * buffer = Util::BufferCacheHolder::Instance().requestBuffer(npot.w * npot.h * bpp);
|
||||
SDL_LockSurface(surface);
|
||||
copyImage2Image(buffer, (uint8_t*)surface->pixels, surface->pitch, surface->h,
|
||||
npot.w * bpp);
|
||||
SDL_UnlockSurface(surface);
|
||||
SDL_FreeSurface(surface);
|
||||
|
||||
GLuint texture = createGLTexture(npot.w, npot.h, (bpp == 4) ? true : false, buffer);
|
||||
return OpenGL::PagedTexture(texture, 0, 0, GLfloat(surface->w)/npot.w,
|
||||
GLfloat(surface->h)/npot.h);
|
||||
}
|
||||
#endif
|
||||
|
||||
GLuint createGLTexture(GLsizei w, GLsizei h, bool rgba, const void* pixels) {
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
if (!mipmapTextures)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
else
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (rgba)
|
||||
if (rgba) {
|
||||
if (mipmapTextures)
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
//gluBuild2DMipmaps(GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
}
|
||||
else {
|
||||
if (mipmapTextures)
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
||||
else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
||||
//gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
||||
}
|
||||
if (supportedMaxAnisoDegree > 1.0f)
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &supportedMaxAnisoDegree);
|
||||
|
||||
GL_CHECKERROR;
|
||||
return tex;
|
||||
@ -165,13 +203,86 @@ using OpenGL::PagedTexture;
|
||||
bool rgba, const void* pixels) {
|
||||
|
||||
NextPowerOfTwo npot(w, h);
|
||||
uint32_t bpp = (rgba ? 4 : 3);
|
||||
uint8_t* buff = (uint8_t*)pixels;
|
||||
|
||||
if (!(npot.w == uint32_t(w) && npot.h == uint32_t(h))) {
|
||||
uint32_t bpp = (rgba ? 4 : 3);
|
||||
uint32_t bufSize = npot.w * npot.h * bpp;
|
||||
uint8_t* buff = Util::BufferCacheHolder::Instance().requestBuffer(bufSize);
|
||||
buff = Util::BufferCacheHolder::Instance().requestBuffer(bufSize);
|
||||
copyImage2Image(buff, (uint8_t*)pixels, w * bpp, h, npot.w * bpp);
|
||||
}
|
||||
|
||||
GLuint tex = createGLTexture(npot.w, npot.h, rgba, buff);
|
||||
return PagedTexture(tex, 0, 0, float(w) / npot.w, float(h) / npot.h);
|
||||
}
|
||||
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define READINT24(x) ((x)[0]<<16 | (x)[1]<<8 | (x)[2])
|
||||
#define WRITEINT24(x, i) {(x)[0]=i>>16; (x)[1]=(i>>8)&0xff; x[2]=i&0xff; }
|
||||
|
||||
uint8_t* scale2x_24bit(const uint8_t* src, const int src_width, const int src_height) {
|
||||
const int srcpitch = src_width * 3;
|
||||
const int dstpitch = src_width * 6;
|
||||
|
||||
uint8_t *dstpix = Util::BufferCacheHolder::Instance().requestBuffer(src_width *
|
||||
src_height * 3 * 4);
|
||||
int E0, E1, E2, E3, B, D, E, F, H;
|
||||
for(int looph = 0; looph < src_height; ++looph)
|
||||
{
|
||||
for(int loopw = 0; loopw < src_width; ++ loopw)
|
||||
{
|
||||
B = READINT24(src + (MAX(0,looph-1)*srcpitch) + (3*loopw));
|
||||
D = READINT24(src + (looph*srcpitch) + (3*MAX(0,loopw-1)));
|
||||
E = READINT24(src + (looph*srcpitch) + (3*loopw));
|
||||
F = READINT24(src + (looph*srcpitch) + (3*MIN(src_width-1,loopw+1)));
|
||||
H = READINT24(src + (MIN(src_height-1,looph+1)*srcpitch) + (3*loopw));
|
||||
|
||||
E0 = D == B && B != F && D != H ? D : E;
|
||||
E1 = B == F && B != D && F != H ? F : E;
|
||||
E2 = D == H && D != B && H != F ? D : E;
|
||||
E3 = H == F && D != H && B != F ? F : E;
|
||||
|
||||
WRITEINT24((dstpix + looph*2*dstpitch + loopw*2*3), E0);
|
||||
WRITEINT24((dstpix + looph*2*dstpitch + (loopw*2+1)*3), E1);
|
||||
WRITEINT24((dstpix + (looph*2+1)*dstpitch + loopw*2*3), E2);
|
||||
WRITEINT24((dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*3), E3);
|
||||
}
|
||||
}
|
||||
return dstpix;
|
||||
}
|
||||
|
||||
uint8_t* scale2x_32bit(const uint8_t* src, const int src_width, const int src_height) {
|
||||
const int srcpitch = src_width * 4;
|
||||
const int dstpitch = src_width * 8;
|
||||
|
||||
uint8_t* dstpix = Util::BufferCacheHolder::Instance().requestBuffer(src_width *
|
||||
src_height * 4 * 4);
|
||||
Uint32 E0, E1, E2, E3, B, D, E, F, H;
|
||||
for(int looph = 0; looph < src_height; ++looph)
|
||||
{
|
||||
for(int loopw = 0; loopw < src_width; ++ loopw)
|
||||
{
|
||||
B = *(Uint32*)(src + (MAX(0,looph-1)*srcpitch) + (4*loopw));
|
||||
D = *(Uint32*)(src + (looph*srcpitch) + (4*MAX(0,loopw-1)));
|
||||
E = *(Uint32*)(src + (looph*srcpitch) + (4*loopw));
|
||||
F = *(Uint32*)(src + (looph*srcpitch) + (4*MIN(src_width-1,loopw+1)));
|
||||
H = *(Uint32*)(src + (MIN(src_height-1,looph+1)*srcpitch) + (4*loopw));
|
||||
|
||||
E0 = D == B && B != F && D != H ? D : E;
|
||||
E1 = B == F && B != D && F != H ? F : E;
|
||||
E2 = D == H && D != B && H != F ? D : E;
|
||||
E3 = H == F && D != H && B != F ? F : E;
|
||||
|
||||
*(Uint32*)(dstpix + looph*2*dstpitch + loopw*2*4) = E0;
|
||||
*(Uint32*)(dstpix + looph*2*dstpitch + (loopw*2+1)*4) = E1;
|
||||
*(Uint32*)(dstpix + (looph*2+1)*dstpitch + loopw*2*4) = E2;
|
||||
*(Uint32*)(dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*4) = E3;
|
||||
}
|
||||
}
|
||||
return dstpix;
|
||||
}
|
||||
|
||||
bool mipmapTextures = false;
|
||||
GLfloat supportedMaxAnisoDegree = 1.0f;
|
||||
}
|
||||
|
@ -29,8 +29,8 @@
|
||||
|
||||
namespace ImageUtil {
|
||||
|
||||
typedef std::pair<uint16_t, uint16_t> WidthHeightPair;
|
||||
|
||||
/** Helper to calculate 2^k texture sizes.
|
||||
*/
|
||||
struct NextPowerOfTwo {
|
||||
NextPowerOfTwo(uint32_t _w, uint32_t _h) {
|
||||
w = 1; h = 1;
|
||||
@ -41,22 +41,41 @@ namespace ImageUtil {
|
||||
uint32_t h;
|
||||
};
|
||||
|
||||
/** Run scale2x on 32bit input image.
|
||||
*
|
||||
* \note Uses Util::BufferCache for dst memory; lock 'src' before calling
|
||||
* if it also is a BufferCache buffer.
|
||||
*/
|
||||
uint8_t* scale2x_32bit(const uint8_t* src, const int src_width, const int src_height);
|
||||
|
||||
uint8_t* scale2x_24bit(const uint8_t* src, const int src_width, const int src_height);
|
||||
|
||||
typedef std::pair<uint16_t, uint16_t> WidthHeightPair;
|
||||
// hardcoded data for known images
|
||||
WidthHeightPair lookupImageSize(const std::string & name, const uint32_t size);
|
||||
// load a rgb image
|
||||
OpenGL::PagedTexture loadImageRAW(const std::string & name);
|
||||
// load a palette image and guess the palette filename
|
||||
OpenGL::PagedTexture loadImageRAT(const std::string & name);
|
||||
//OpenGL::PagedTexture loadImageRAT(const std::string & name);
|
||||
// load a palette image using palette file
|
||||
OpenGL::PagedTexture loadImageRATWithPalette(const std::string & name,
|
||||
const std::string & palette_file);
|
||||
// plain simple garden-variety create-a-texture; needs to be ^2
|
||||
GLuint createGLTexture(GLsizei w, GLsizei h, bool rgba, const void* pixels);
|
||||
#ifdef WITH_SDL_IMAGE
|
||||
OpenGL::PagedTexture loadImageSDL(const std::string & name);
|
||||
#endif
|
||||
|
||||
// blitting a buffer into another; they should exist!
|
||||
extern bool mipmapTextures;
|
||||
extern GLfloat supportedMaxAnisoDegree;
|
||||
|
||||
// plain simple garden-variety create-a-texture; needs to be 2^k
|
||||
GLuint createGLTexture(GLsizei w, GLsizei h, bool rgba,
|
||||
const void* pixels);
|
||||
|
||||
// blitting a buffer into another; no checks done!
|
||||
void copyImage2Image(uint8_t *dest, const uint8_t *src, const uint16_t
|
||||
srcWidth, const uint16_t srcHeight, const uint16_t destWidth);
|
||||
|
||||
// texture-class instance from pixel data; does transform to 2^k if required
|
||||
OpenGL::PagedTexture createEmbeddedTexture(GLsizei w, GLsizei h, bool rgba,
|
||||
const void *pixels);
|
||||
}
|
||||
|
68
util/key_handler.cpp
Normal file
68
util/key_handler.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/************************************************************************
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#include <SDL_keysym.h>
|
||||
#include "key_handler.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace Util {
|
||||
bool IngameCommonKeys::up(const uint32_t & key) {
|
||||
bool handled = false;
|
||||
return handled;
|
||||
}
|
||||
|
||||
bool IngameCommonKeys::down(const uint32_t & key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void KeyHandlerChain::up(const uint32_t & key) {
|
||||
for (ListOfHandlers::iterator i = activeHandlers.begin();
|
||||
i != activeHandlers.end(); i++) {
|
||||
if ((*i)->up(key))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyHandlerChain::down(const uint32_t & key) {
|
||||
for (ListOfHandlers::iterator i = activeHandlers.begin();
|
||||
i != activeHandlers.end(); i++) {
|
||||
if ((*i)->down(key))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyHandlerChain::addHandler(KeyHandler * kh, bool front) {
|
||||
if (front)
|
||||
activeHandlers.push_front(kh);
|
||||
else
|
||||
activeHandlers.push_back(kh);
|
||||
}
|
||||
|
||||
void KeyHandlerChain::removeHandler(KeyHandler * kh) {
|
||||
for (ListOfHandlers::iterator i = activeHandlers.begin();
|
||||
i != activeHandlers.end(); i++) {
|
||||
if (kh == *i)
|
||||
activeHandlers.erase(i);
|
||||
}
|
||||
ERROR << "not a valid handler pointer" << std::endl;
|
||||
}
|
||||
}
|
86
util/key_handler.h
Normal file
86
util/key_handler.h
Normal file
@ -0,0 +1,86 @@
|
||||
/************************************************************************
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#ifndef UTIL_KEYHANDLER_H
|
||||
#define UTIL_KEYHANDLER_H
|
||||
#include <stdint.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include "pf_tree.hpp"
|
||||
|
||||
namespace Util {
|
||||
|
||||
/** Interface for key listeners.
|
||||
*
|
||||
* Must implement both keypress and release functions;
|
||||
* the functions should return \em true when the input
|
||||
* value is consumed by a handler.
|
||||
*/
|
||||
class KeyHandler {
|
||||
public:
|
||||
virtual ~KeyHandler() {}
|
||||
virtual bool up(const uint32_t & key) = 0;
|
||||
virtual bool down(const uint32_t & key) = 0;
|
||||
};
|
||||
|
||||
/** Keys that do _not_ control the player character.
|
||||
*/
|
||||
class IngameCommonKeys : public KeyHandler {
|
||||
public:
|
||||
bool up(const uint32_t & key);
|
||||
bool down(const uint32_t & key);
|
||||
};
|
||||
|
||||
class MenuKeys : public KeyHandler {
|
||||
public:
|
||||
bool up(const uint32_t & key);
|
||||
bool down(const uint32_t & key);
|
||||
};
|
||||
|
||||
class CheatKeys : public KeyHandler {
|
||||
public:
|
||||
bool up(const uint32_t & key);
|
||||
bool down(const uint32_t & key);
|
||||
template <typename T>
|
||||
struct Callback_Lua {
|
||||
void call(T);
|
||||
};
|
||||
typedef PrefixFreeTree::Walker<uint32_t, Callback_Lua> TreeOfCheats;
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> cheat_fn_refs;
|
||||
};
|
||||
|
||||
class KeyHandlerChain {
|
||||
public:
|
||||
void up(const uint32_t & key);
|
||||
void down(const uint32_t & key);
|
||||
void addHandler(KeyHandler*, bool front = true);
|
||||
void removeHandler(KeyHandler*);
|
||||
private:
|
||||
typedef std::list<KeyHandler*> ListOfHandlers;
|
||||
ListOfHandlers activeHandlers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
47
util/log.h
47
util/log.h
@ -12,17 +12,58 @@
|
||||
#define ERROR_AND_EXIT(ec) error_code = ec; exit(ec);
|
||||
#define GL_CHECKERROR { int _err = glGetError(); if (_err != GL_NO_ERROR) \
|
||||
Util::Log::error(__FILE__, __LINE__) << "GL error: " << _err << " = " << Util::Log::glErrorName(_err) << std::endl; }
|
||||
|
||||
#define ANSI_COLOR_OFF "\033[0m"
|
||||
#define ANSI_COLOR_INFO "\033[32mInfo ("
|
||||
#define ANSI_COLOR_WARN "\033[33mWarning ("
|
||||
#define ANSI_COLOR_ERR "\033[31mError ("
|
||||
|
||||
namespace Util {
|
||||
class Log {
|
||||
public:
|
||||
inline static std::ostream & info(const char* f, int l) {
|
||||
if (level) return emptyStream; std::cout << "Info (" << f << ":" << l << "): "; return std::cout;
|
||||
if (level) return emptyStream;
|
||||
#ifdef LOG_USE_ANSI_COLORS
|
||||
std::cout << ANSI_COLOR_INFO <<
|
||||
#else
|
||||
std::cout << "Info (" <<
|
||||
#endif
|
||||
f << ":" << l << "): "
|
||||
#ifdef LOG_USE_ANSI_COLORS
|
||||
<< ANSI_COLOR_OFF;
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
return std::cout;
|
||||
}
|
||||
inline static std::ostream & warn(const char* f, int l) {
|
||||
if (level > 1) return emptyStream; std::cerr << "Warning (" << f << ":" << l << "): "; return std::cerr;
|
||||
if (level > 1) return emptyStream;
|
||||
#ifdef LOG_USE_ANSI_COLORS
|
||||
std::cerr << ANSI_COLOR_WARN <<
|
||||
#else
|
||||
std::cerr << "Warning (" <<
|
||||
#endif
|
||||
f << ":" << l << "): "
|
||||
#ifdef LOG_USE_ANSI_COLORS
|
||||
<< ANSI_COLOR_OFF;
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
return std::cerr;
|
||||
}
|
||||
inline static std::ostream & error(const char* f, int l) {
|
||||
std::cerr << "Error ("<< f << ":" << l << "): "; return std::cerr;
|
||||
#ifdef LOG_USE_ANSI_COLORS
|
||||
std::cerr << ANSI_COLOR_ERR <<
|
||||
#else
|
||||
std::cerr << "Error (" <<
|
||||
#endif
|
||||
f << ":" << l << "): "
|
||||
#ifdef LOG_USE_ANSI_COLORS
|
||||
<< ANSI_COLOR_OFF;
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
return std::cerr;
|
||||
}
|
||||
static void setOutputLevel(unsigned int newLevel);
|
||||
static const char* glErrorName(int k);
|
||||
|
@ -4,6 +4,22 @@
|
||||
namespace Util {
|
||||
void SpriteCreationArea::setRects(const SDL_Rect & allowed, const SDL_Rect & denied) {
|
||||
validRects = std::make_pair<SDL_Rect, SDL_Rect>(allowed, denied);
|
||||
onScreen = denied;
|
||||
}
|
||||
|
||||
bool SpriteCreationArea::isOnScreen(const Vector3D & p) {
|
||||
/* INFO << p.x << " " << p.y << " " << p.z << std::endl;
|
||||
INFO << onScreen.x <<", " << onScreen.y << " -> " <<
|
||||
onScreen.x + onScreen.w << ", " << onScreen.y + onScreen.h << std::endl;
|
||||
*/
|
||||
if ((p.x >= onScreen.x) && (p.x <= onScreen.x + onScreen.w) &&
|
||||
(p.z >= onScreen.y) && (p.z <= onScreen.y + onScreen.h))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpriteCreationArea::isOffScreen(const Vector3D & p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TupleOfUint8 SpriteCreationArea::getValidCoord() {
|
||||
@ -11,4 +27,29 @@ namespace Util {
|
||||
uint32_t y = rnd.nextUint(validRects.first.h) + validRects.first.y;
|
||||
return std::make_pair<uint8_t, uint8_t>(x, y);
|
||||
}
|
||||
|
||||
int item_count(MapOfPair2Int & m, int a, int b) {
|
||||
MapOfPair2Int::iterator j = m.find( std::make_pair<int, int>(a, b) );
|
||||
if (j == m.end())
|
||||
return 0;
|
||||
return j->second;
|
||||
}
|
||||
|
||||
void register_item1(MapOfPair2Int & m, int a, int b) {
|
||||
m.insert( std::make_pair< Pair2Int, int>(
|
||||
std::make_pair<int, int>(a, b),
|
||||
1)
|
||||
);
|
||||
}
|
||||
|
||||
void register_item(MapOfPair2Int & m, int a, int b) {
|
||||
Pair2Int _p(std::make_pair<int, int>(a, b));
|
||||
MapOfPair2Int::iterator j = m.find(_p);
|
||||
if (j == m.end())
|
||||
register_item1(m, a, b);
|
||||
else
|
||||
j->second++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,10 @@
|
||||
#define MAP_HELPER_H
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <SDL_video.h>
|
||||
#include <cassert> // yasli/random.h needs it
|
||||
#include "math3d.h"
|
||||
#include "yasli/random.h"
|
||||
|
||||
namespace Util {
|
||||
@ -17,6 +20,42 @@ namespace Util {
|
||||
void setRects(const SDL_Rect & allowed, const SDL_Rect & denied);
|
||||
TupleOfUint8 getValidCoord();
|
||||
Random rnd;
|
||||
bool isOnScreen(const Vector3D & p);
|
||||
bool isOffScreen(const Vector3D & p);
|
||||
private:
|
||||
SDL_Rect onScreen;
|
||||
};
|
||||
|
||||
|
||||
/** lesser than comparison of two std::pair<int, int>.
|
||||
*/
|
||||
template <typename T>
|
||||
struct lt_pair {
|
||||
bool operator() (const T & a, const T & b) {
|
||||
if (a.first < b.first)
|
||||
return true;
|
||||
if (a.first > b.first)
|
||||
return false;
|
||||
return (a.second < b.second);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::pair<int, int> Pair2Int;
|
||||
typedef lt_pair<std::pair<int, int> > cmp_Pair2Int;
|
||||
typedef std::map<Pair2Int, int, cmp_Pair2Int> MapOfPair2Int;
|
||||
|
||||
/** count of Pair2Int(a,b) in the map.
|
||||
* @return 0 if no entry at that \e position
|
||||
* @return count otherwise
|
||||
*/
|
||||
int item_count(MapOfPair2Int & m, int a, int b);
|
||||
/** insert (may overwrite) count 1 at Pair2Int(a, b).
|
||||
*/
|
||||
void register_item1(MapOfPair2Int & m, int a, int b);
|
||||
/** register and count Pair2Int(a, b).
|
||||
*/
|
||||
void register_item(MapOfPair2Int & m, int a, int b);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
96
util/pf_tree.cpp
Normal file
96
util/pf_tree.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
/************************************************************************
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#include "pf_tree.hpp"
|
||||
namespace PrefixFreeTree {
|
||||
|
||||
Node::~Node() {
|
||||
for (MapType::iterator i = map.begin(); i != map.end(); i++) {
|
||||
delete i->second;
|
||||
}
|
||||
map.clear();
|
||||
}
|
||||
|
||||
Node & Node::insert(const char * str, size_t offset) {
|
||||
size_t str_len = strlen(str);
|
||||
if (offset < str_len) {
|
||||
value_t node_val = str[offset];
|
||||
MapType::iterator i = map.find(node_val);
|
||||
offset++;
|
||||
if (i == map.end()) {
|
||||
map[node_val] = new Node();
|
||||
return map[node_val]->insert(str, offset);
|
||||
}
|
||||
else {
|
||||
if (i->second->isLeaf()) {
|
||||
std::ostringstream os;
|
||||
os << "Cannot enter '" << str << "' at offset " << offset <<
|
||||
" as a leaf node already exists";
|
||||
throw E_INVALIDFORMAT(os.str());
|
||||
}
|
||||
if ((offset == str_len) && (!i->second->isLeaf())) {
|
||||
std::ostringstream os;
|
||||
os << "Cannot enter '" << str
|
||||
<< "' as a non-leaf node already exists" << std::endl;
|
||||
throw E_INVALIDFORMAT(os.str());
|
||||
}
|
||||
return i->second->insert(str, offset);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef SIMPLE_TREE_DEMO
|
||||
#include <iostream>
|
||||
|
||||
template <typename T>
|
||||
struct Echo {
|
||||
void call(T t) {
|
||||
std::cout << "Echo: " << t << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
using namespace std;
|
||||
int main(int argc, char* argv[]) {
|
||||
PrefixFreeTree::Walker<uint32_t, Echo> m;
|
||||
uint32_t i = 1;
|
||||
while (!cin.eof()) {
|
||||
std::string inputs;
|
||||
cin >> inputs;
|
||||
if (inputs.size()) {
|
||||
std::cout << "-" << inputs << "-" << std::endl;
|
||||
PrefixFreeTree::Node & n = m.insert(inputs.c_str());
|
||||
n.leaf_value = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
const char* input = argv[1];
|
||||
int len = strlen(input);
|
||||
for (int i = 0; i < len; i++) {
|
||||
m.push(input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
75
util/pf_tree.hpp
Normal file
75
util/pf_tree.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
/************************************************************************
|
||||
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||
* *
|
||||
* This software is provided as-is, without any express or implied *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
* damages arising from the use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute *
|
||||
* it freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must *
|
||||
* not claim that you wrote the original software. If you use this *
|
||||
* software in a product, an acknowledgment in the product documentation *
|
||||
* would be appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must *
|
||||
* not be misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#ifndef PREFIX_FREE_TREE_H
|
||||
#define PREFIX_FREE_TREE_H
|
||||
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "m_exceptions.h"
|
||||
|
||||
namespace PrefixFreeTree {
|
||||
|
||||
struct Node {
|
||||
~Node();
|
||||
typedef int value_t;
|
||||
uint32_t leaf_value;
|
||||
typedef std::map<value_t, Node* > MapType;
|
||||
MapType map;
|
||||
bool isLeaf() const { return (map.size() == 0); }
|
||||
Node & insert(const char * str, size_t offset = 0);
|
||||
};
|
||||
|
||||
#define CHECK_HANDLE_LEAF if (curPos->isLeaf()) { Handler<T>::call(curPos->leaf_value); }
|
||||
|
||||
template <typename T, template <class> class Handler>
|
||||
class Walker : public Handler<T>, public Node {
|
||||
public:
|
||||
Walker() : Handler<T>(), Node(), curPos(this) {}
|
||||
|
||||
void push(int v) {
|
||||
MapType::iterator i = curPos->map.find(v);
|
||||
if (i != curPos->map.end()) {
|
||||
curPos = i->second;
|
||||
CHECK_HANDLE_LEAF;
|
||||
}
|
||||
else {
|
||||
i = map.find(v);
|
||||
if (i != map.end()) {
|
||||
curPos = i->second;
|
||||
CHECK_HANDLE_LEAF;
|
||||
}
|
||||
else
|
||||
curPos = this;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Node * curPos;
|
||||
};
|
||||
|
||||
}
|
||||
#undef CHECK_HANDLE_LEAF
|
||||
|
||||
#endif
|
@ -46,7 +46,12 @@ namespace Audio {
|
||||
OpenGTA::SoundsDB::Entry & e = db.getEntry(idx);
|
||||
size_t si;
|
||||
unsigned char* mem = db.getBuffered(idx);
|
||||
Uint8 *mem2 = (Uint8*)Audio::resample_new(mem, e.rawSize, si, e.sampleRate, 44100);
|
||||
Uint8 *mem2 = NULL;
|
||||
if (file.find("000") != std::string::npos) {
|
||||
mem2 = (Uint8*)Audio::resample16(mem, e.rawSize, si, e.sampleRate, 44100);
|
||||
}
|
||||
else
|
||||
mem2 = (Uint8*)Audio::resample_new(mem, e.rawSize, si, e.sampleRate, 44100);
|
||||
Mix_Chunk * music = Mix_QuickLoad_RAW(mem2, si);
|
||||
return ChunkData(mem2, music, 1);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
* 3. This notice may not be removed or altered from any source *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#include <iostream>
|
||||
#include "sound_resample2.h"
|
||||
#include "interpolate.hpp"
|
||||
|
||||
@ -89,4 +90,58 @@ namespace Audio {
|
||||
while (src < src_end);
|
||||
return stereo_data;
|
||||
}
|
||||
|
||||
Sint16 *resample16 (Uint8 * src, size_t sourcelen, size_t & size,
|
||||
int rate, int wanted_rate) {
|
||||
int fp_pos = 0;
|
||||
int fp_speed = (1 << 16) * rate / wanted_rate;
|
||||
size = sourcelen;
|
||||
while (size & 0xFFFF0000)
|
||||
size >>= 1, rate = (rate >> 1) + 1;
|
||||
size = (size * wanted_rate / rate) << 1;
|
||||
|
||||
Sint16 *stereo_data = new Sint16[size];
|
||||
Sint16 *data = stereo_data;
|
||||
Uint8 *src_end = src + sourcelen;
|
||||
|
||||
int result;
|
||||
int a = *(src + 0);
|
||||
a = a + (*(src + 1) << 8);
|
||||
int b = *(src + 2);
|
||||
b = b + (*(src + 3) << 8);
|
||||
int c = *(src + 4);
|
||||
c = c + (*(src + 5) << 8);
|
||||
|
||||
|
||||
std::cout << a << " " << b << " " << c << std::endl;
|
||||
Math::Interpolator::Cubic<float> inter(a * 0.8333f, b * 0.8333f, c * 0.8333f);
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
result = int(inter.getAt(fp_pos / float(0x0000FFFF)));
|
||||
if (result < -32768)
|
||||
result = -32768;
|
||||
else if (result > 32767)
|
||||
result = 32767;
|
||||
*data++ = result;
|
||||
|
||||
fp_pos += fp_speed;
|
||||
}
|
||||
while (!(fp_pos & 0xFFFF0000));
|
||||
src++;
|
||||
fp_pos &= 0x0000FFFF;
|
||||
if (src + 2 < src_end)
|
||||
{
|
||||
c = *(src + 2);
|
||||
c = c + (*(src + 3) << 8);
|
||||
inter.shiftAndFeed (c * 0.8333f);
|
||||
}
|
||||
else
|
||||
inter.shift ();
|
||||
}
|
||||
while (src < src_end);
|
||||
return stereo_data;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace Audio
|
||||
{
|
||||
Sint16 *resample_new (Uint8 * sourcedata, size_t sourcelen,
|
||||
size_t & destlen, int current_rate, int wanted_rate);
|
||||
Sint16 *resample_new_mono (Uint8 * sourcedata, size_t sourcelen,
|
||||
Sint16 *resample16 (Uint8 * sourcedata, size_t sourcelen,
|
||||
size_t & destlen, int current_rate,
|
||||
int wanted_rate);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include "sound_system.h"
|
||||
#include "sound_music_player.h"
|
||||
#include "physfsrwops.h"
|
||||
#include "m_exceptions.h"
|
||||
#include "log.h"
|
||||
@ -10,7 +11,12 @@ namespace Audio {
|
||||
#ifdef WITH_SOUND
|
||||
SoundSystem::SoundSystem() : device(), chunkCache() {
|
||||
SDL_InitSubSystem(SDL_INIT_AUDIO);
|
||||
try {
|
||||
device.open();
|
||||
}
|
||||
catch (const Exception & e) {
|
||||
ERROR << e.what() << std::endl;
|
||||
}
|
||||
enabled = true;
|
||||
if (device.getStatus() == SoundDevice::OPEN)
|
||||
Sound_Init();
|
||||
@ -59,6 +65,8 @@ namespace Audio {
|
||||
}
|
||||
|
||||
void SoundSystem::listMusicDecoders() {
|
||||
if (!enabled)
|
||||
return;
|
||||
std::cout << "* Supported music decoders *" << std::endl;
|
||||
const Sound_DecoderInfo **i;
|
||||
for (i = Sound_AvailableDecoders(); *i != NULL; i++) {
|
||||
@ -91,7 +99,13 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
SoundSystem noisemaker;
|
||||
noisemaker.listMusicDecoders();
|
||||
if (argc == 2)
|
||||
noisemaker.playMusic(argv[1]);
|
||||
if (argc == 3) {
|
||||
noisemaker.playFx(argv[1], atoi(argv[2]));
|
||||
while (Mix_Playing(-1))
|
||||
SDL_Delay(500);
|
||||
}
|
||||
MusicPlayerCtrl::musicFinishedCB = CB_MusicDone;
|
||||
while (MusicPlayerCtrl::isPlaying) {
|
||||
SDL_Delay(1000);
|
||||
|
@ -18,8 +18,8 @@ namespace Audio {
|
||||
SoundSystem();
|
||||
~SoundSystem();
|
||||
void playFx(std::string file, size_t idx);
|
||||
void SoundSystem::playMusic(std::string file);
|
||||
void SoundSystem::listMusicDecoders();
|
||||
void playMusic(std::string file);
|
||||
void listMusicDecoders();
|
||||
bool enabled;
|
||||
};
|
||||
}
|
||||
|
510
viewer.cpp
510
viewer.cpp
@ -42,10 +42,15 @@
|
||||
#include "navdata.h"
|
||||
#include "opengta.h"
|
||||
#include "spritemanager.h"
|
||||
#include "gl_spritecache.h"
|
||||
#include "timer.h"
|
||||
#ifdef WITH_LUA
|
||||
#include "lua_addon/lua_vm.h"
|
||||
#include "lua_addon/lua_stackguard.h"
|
||||
#endif
|
||||
#include "gui.h"
|
||||
#include "font_cache.h"
|
||||
#include "ai.h"
|
||||
|
||||
#define getPedById getPed
|
||||
#define removePedById removePed
|
||||
@ -54,10 +59,12 @@
|
||||
extern SDL_Surface* screen;
|
||||
extern int global_EC;
|
||||
extern int global_Done;
|
||||
extern int global_Restart;
|
||||
GLfloat mapPos[3] = {12.0f, 12.0f, 20.0f};
|
||||
|
||||
OpenGTA::CityView *city = NULL;
|
||||
OpenGL::DrawableFont* m_font = NULL;
|
||||
//OpenGL::DrawableFont* m_font = NULL;
|
||||
GUI::Label * fps_label = NULL;
|
||||
|
||||
int city_num = 0;
|
||||
const char* styles_8[3] = { "STYLE001.GRY", "STYLE002.GRY", "STYLE003.GRY" };
|
||||
@ -81,6 +88,11 @@ int ped_anim = 0;
|
||||
int bbox_toggle = 0;
|
||||
int texsprite_toggle = 0;
|
||||
int follow_toggle = 0;
|
||||
float anisotropic_filter_degree = 2.0f;
|
||||
int mipmap_textures = -1;
|
||||
int vsync_config = -1;
|
||||
int city_blocks_area = -1;
|
||||
int config_scale2x = 1;
|
||||
OpenGTA::SpriteObject::Animation pedAnim(0, 0);
|
||||
#ifdef OGTA_DEFAULT_GRAPHICS_G24
|
||||
bool highcolor_data = true;
|
||||
@ -93,6 +105,10 @@ bool player_toggle_run = false;
|
||||
const char* script_file = NULL;
|
||||
int paused = 0;
|
||||
int next_station_zoom = 0;
|
||||
bool gamma_slide = false;
|
||||
float screen_gamma = 1.0f;
|
||||
|
||||
Vector3D test_dot(-1, -1, -1);
|
||||
|
||||
/*
|
||||
void ERROR(const char* s) {
|
||||
@ -106,8 +122,8 @@ void on_exit() {
|
||||
SDL_Quit();
|
||||
if (city)
|
||||
delete city;
|
||||
if (m_font)
|
||||
delete m_font;
|
||||
//if (m_font)
|
||||
// delete m_font;
|
||||
PHYSFS_deinit();
|
||||
if (global_EC)
|
||||
std::cerr << "Exiting after fatal problem - please see output above" << std::endl;
|
||||
@ -123,6 +139,17 @@ void print_usage(const char* argv0) {
|
||||
" -c k : 0 = 8bit GRY, 1 = 24bit G24" << std::endl <<
|
||||
" -f : fullscreen on program-start" << std::endl <<
|
||||
" -V : show version & compile-time switches" << std::endl <<
|
||||
" -M k : texture mipmaps: 0 = disable, 1 = enable" << std::endl <<
|
||||
" -x k : scale2x sprites: 0 = disable, 1 = enable" << std::endl <<
|
||||
" -v k : vertical sync: 0 = disable, 1 = try with SDL" <<
|
||||
#ifdef LINUX
|
||||
", 2 = try with GLX" <<
|
||||
#elif WIN32
|
||||
", 2 = try with GLW" <<
|
||||
#endif
|
||||
std::endl <<
|
||||
" -a f : anisotropic texture filtering degree: 1.0 = disabled"
|
||||
<< std::endl <<
|
||||
std::endl <<
|
||||
" -m map_file -g style_file : load specified files" << std::endl <<
|
||||
" -w width -h height : screen dimension" << std::endl <<
|
||||
@ -132,12 +159,13 @@ void print_usage(const char* argv0) {
|
||||
"The following environment variables are used when defined:" << std::endl <<
|
||||
" OGTA_DATA : PhysicsFS source for main data file lookup" << std::endl <<
|
||||
" OGTA_HOME : unused - will be config/save dir" << std::endl <<
|
||||
" OGTA_MOD : PhysicsFS source to override main data files" << std::endl;
|
||||
" OGTA_MOD : PhysicsFS source to override main data files" << std::endl <<
|
||||
" OGTA_LANG : defines the fxt language file to load" << std::endl;
|
||||
}
|
||||
|
||||
void print_version_info() {
|
||||
#define PRINT_FORMATED(spaces) std::setw(spaces) << std::left <<
|
||||
#define PRINT_OFFSET PRINT_FORMATED(18)
|
||||
#define PRINT_OFFSET PRINT_FORMATED(19)
|
||||
std::cout << PRINT_OFFSET "OpenGTA version:" << OGTA_VERSION_INFO << std::endl <<
|
||||
PRINT_OFFSET "platform:" << OGTA_PLATFORM_INFO << std::endl <<
|
||||
|
||||
@ -155,11 +183,26 @@ void print_version_info() {
|
||||
"no" <<
|
||||
#endif
|
||||
std::endl <<
|
||||
PRINT_OFFSET "SDL_image support:" <<
|
||||
#ifdef WITH_SDL_IMAGE
|
||||
"yes" <<
|
||||
#else
|
||||
"no" <<
|
||||
#endif
|
||||
std::endl <<
|
||||
|
||||
PRINT_OFFSET "vsync support:" <<
|
||||
#ifdef HAVE_SDL_VSYNC
|
||||
"yes" <<
|
||||
#else
|
||||
"no" <<
|
||||
#endif
|
||||
std::endl <<
|
||||
PRINT_OFFSET "scale2x support:" <<
|
||||
#ifdef DO_SCALE2X
|
||||
"yes" <<
|
||||
#else
|
||||
"no" <<
|
||||
#endif
|
||||
std::endl <<
|
||||
|
||||
@ -188,24 +231,30 @@ void parse_args(int argc, char* argv[]) {
|
||||
opterr = 0;
|
||||
|
||||
#ifdef WITH_LUA
|
||||
#define VIEWER_FLAGS "s:w:h:c:m:g:l:fV"
|
||||
#define VIEWER_FLAGS "a:s:w:h:c:m:M:g:l:v:x:fV"
|
||||
#else
|
||||
#define VIEWER_FLAGS "w:h:c:m:g:l:fV"
|
||||
#define VIEWER_FLAGS "a:w:h:c:m:M:g:l:v:x:fV"
|
||||
#endif
|
||||
while ((c = getopt (argc, argv, VIEWER_FLAGS)) != -1)
|
||||
switch (c)
|
||||
{
|
||||
#ifdef WITH_LUA
|
||||
case 's':
|
||||
script_file = std::string(optarg);
|
||||
script_file = optarg;
|
||||
break;
|
||||
#endif
|
||||
case 'a':
|
||||
anisotropic_filter_degree = atof(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
highcolor_data = atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
specific_map = std::string(optarg);
|
||||
break;
|
||||
case 'M':
|
||||
mipmap_textures = atoi(optarg);
|
||||
break;
|
||||
case 'g':
|
||||
specific_style = std::string(optarg);
|
||||
break;
|
||||
@ -221,10 +270,16 @@ void parse_args(int argc, char* argv[]) {
|
||||
case 'f':
|
||||
full_screen = true;
|
||||
break;
|
||||
case 'v':
|
||||
vsync_config = atoi(optarg);
|
||||
break;
|
||||
case 'V':
|
||||
print_version_info();
|
||||
exit(0);
|
||||
break;
|
||||
case 'x':
|
||||
config_scale2x = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
if (optopt == '?') {
|
||||
print_usage(argv[0]);
|
||||
@ -254,7 +309,7 @@ void run_init(const char* prg_name) {
|
||||
// physfs-ogta
|
||||
Util::FileHelper & fh = GET_FILE_HELPER;
|
||||
if (fh.existsInSystemFS(fh.getBaseDataPath())) {
|
||||
PHYSFS_addToSearchPath(GET_FILE_HELPER.getBaseDataPath().c_str(), 1);
|
||||
PHYSFS_addToSearchPath(fh.getBaseDataPath().c_str(), 1);
|
||||
}
|
||||
else {
|
||||
WARN << "Could not load data-source: " << fh.getBaseDataPath() << std::endl;
|
||||
@ -263,10 +318,12 @@ void run_init(const char* prg_name) {
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
|
||||
if (fh.existsInSystemFS(fh.getModDataPath()))
|
||||
PHYSFS_addToSearchPath(GET_FILE_HELPER.getModDataPath().c_str(), 0);
|
||||
|
||||
PHYSFS_addToSearchPath(fh.getModDataPath().c_str(), 0);
|
||||
|
||||
// screen, no window yet
|
||||
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||
|
||||
// check for a configfile
|
||||
#ifdef WITH_LUA
|
||||
if (fh.existsInVFS("config")) {
|
||||
char* config_as_string = (char*)fh.bufferFromVFS(
|
||||
@ -274,7 +331,17 @@ void run_init(const char* prg_name) {
|
||||
|
||||
OpenGTA::Script::LuaVM & vm = OpenGTA::Script::LuaVMHolder::Instance();
|
||||
try {
|
||||
vm.runString(config_as_string);
|
||||
//vm.runString(config_as_string);
|
||||
lua_State *L = vm.getInternalState();
|
||||
Util::LGUARD(L);
|
||||
if (luaL_loadbuffer(L, config_as_string, strlen(config_as_string), "config"))
|
||||
throw E_SCRIPTERROR("Error running string: " + std::string(lua_tostring(L, -1)));
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "config");
|
||||
lua_setfenv(L, -2);
|
||||
if (lua_pcall(L, 0, 0, 0))
|
||||
throw E_SCRIPTERROR("Error running string: " + std::string(lua_tostring(L, -1)));
|
||||
}
|
||||
catch (const Util::ScriptError & e) {
|
||||
std::cerr << "Error in config-file: " << e.what() << std::endl;
|
||||
@ -282,20 +349,33 @@ void run_init(const char* prg_name) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lua_State *L = vm.getInternalState();
|
||||
lua_getglobal(L, "config");
|
||||
if (lua_type(L, 1) == LUA_TTABLE) {
|
||||
try {
|
||||
Uint32 sw = vm.getGlobalInt("screen_width");
|
||||
bool sh = vm.getBool("use_g24_graphics");
|
||||
highcolor_data = sh;
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
try {
|
||||
Uint32 sw = vm.getInt("screen_width");
|
||||
if (!arg_screen_w)
|
||||
arg_screen_w = sw;
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
try {
|
||||
Uint32 sh = vm.getGlobalInt("screen_height");
|
||||
Uint32 sh = vm.getInt("screen_height");
|
||||
if (!arg_screen_h)
|
||||
arg_screen_h = sh;
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
try {
|
||||
Uint32 sh = vm.getGlobalInt("full_screen");
|
||||
int sh = vm.getInt("screen_vsync");
|
||||
screen.setupVsync(sh);
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
try {
|
||||
bool sh = vm.getBool("full_screen");
|
||||
if (!full_screen)
|
||||
full_screen = sh;
|
||||
}
|
||||
@ -305,31 +385,111 @@ void run_init(const char* prg_name) {
|
||||
float np = screen.getNearPlane();
|
||||
float fp = screen.getFarPlane();
|
||||
try {
|
||||
fov = vm.getGlobalFloat("field_of_view");
|
||||
fov = vm.getFloat("gl_field_of_view");
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
try {
|
||||
np = vm.getGlobalFloat("near_plane");
|
||||
np = vm.getFloat("gl_near_plane");
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
try {
|
||||
fp = vm.getGlobalFloat("far_plane");
|
||||
fp = vm.getFloat("gl_far_plane");
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
screen.setupGlVars(fov, np, fp);
|
||||
|
||||
try {
|
||||
bool sh = vm.getBool("gl_mipmap_textures");
|
||||
ImageUtil::mipmapTextures = sh;
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
|
||||
try {
|
||||
bool sh = vm.getBool("scale2x_sprites");
|
||||
OpenGL::SpriteCacheHolder::Instance().setScale2x(sh);
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
|
||||
try {
|
||||
int sh = vm.getInt("active_area_size");
|
||||
city_blocks_area = sh;
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
}
|
||||
// can't check for gl-extensions now
|
||||
|
||||
}
|
||||
#endif
|
||||
//INFO << "AREA:: " << city_blocks_area << std::endl;
|
||||
|
||||
|
||||
// check both width & height defined
|
||||
if ((arg_screen_h && !arg_screen_w) || (!arg_screen_h && arg_screen_w)) {
|
||||
WARN << "Invalid screen specified: " << arg_screen_w << "x" <<
|
||||
arg_screen_h << " - using default" << std::endl;
|
||||
arg_screen_h = 0; arg_screen_w = 0;
|
||||
}
|
||||
|
||||
// fullscreen before first video init; only chance to set it on win32
|
||||
screen.setFullScreenFlag(full_screen);
|
||||
if (vsync_config != -1)
|
||||
screen.setupVsync(vsync_config);
|
||||
|
||||
// create screen
|
||||
screen.activate(arg_screen_w, arg_screen_h);
|
||||
SDL_EnableKeyRepeat( 100, SDL_DEFAULT_REPEAT_INTERVAL );
|
||||
|
||||
SDL_EnableKeyRepeat( 0, 0 );
|
||||
//SDL_EnableKeyRepeat( 100, SDL_DEFAULT_REPEAT_INTERVAL );
|
||||
|
||||
// more setup; that requires an active screen
|
||||
#ifdef WITH_LUA
|
||||
OpenGTA::Script::LuaVM & vm = OpenGTA::Script::LuaVMHolder::Instance();
|
||||
lua_State *L = vm.getInternalState();
|
||||
if (lua_type(L, 1) == LUA_TTABLE) {
|
||||
try {
|
||||
float v = vm.getFloat("gl_anisotropic_textures");
|
||||
if (ImageUtil::supportedMaxAnisoDegree >= v)
|
||||
ImageUtil::supportedMaxAnisoDegree = v;
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
try {
|
||||
float v = (highcolor_data ? vm.getFloat("screen_gamma_g24") :
|
||||
vm.getFloat("screen_gamma_gry"));
|
||||
screen_gamma = v;
|
||||
SDL_SetGamma(v, v, v);
|
||||
}
|
||||
catch (const Util::ScriptError & e) {}
|
||||
}
|
||||
lua_settop(L, 0);
|
||||
#endif
|
||||
if (ImageUtil::supportedMaxAnisoDegree >= anisotropic_filter_degree)
|
||||
ImageUtil::supportedMaxAnisoDegree = anisotropic_filter_degree;
|
||||
else
|
||||
WARN << "Using filter degree " << ImageUtil::supportedMaxAnisoDegree <<
|
||||
", requested " << anisotropic_filter_degree << " not supported" << std::endl;
|
||||
|
||||
switch(mipmap_textures) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
ImageUtil::mipmapTextures = false;
|
||||
break;
|
||||
default:
|
||||
ImageUtil::mipmapTextures = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// before any graphics are loaded
|
||||
OpenGL::SpriteCacheHolder::Instance().setScale2x(config_scale2x);
|
||||
|
||||
// FIXME: basic gui setup; should not be here
|
||||
GUI::Manager & gm = GUI::ManagerHolder::Instance();
|
||||
SDL_Rect rect;
|
||||
rect.x = 5;
|
||||
rect.y = 50;
|
||||
fps_label = new GUI::Label(rect, "", "F_MTEXT.FON", 1);
|
||||
//fps_label->borderColor.r = fps_label->borderColor.unused = 200;
|
||||
gm.add(fps_label, 5);
|
||||
}
|
||||
|
||||
|
||||
@ -338,7 +498,7 @@ void print_position() {
|
||||
Vector3D & e = OpenGL::CameraHolder::Instance().getEye();
|
||||
Vector3D & u = OpenGL::CameraHolder::Instance().getUp();
|
||||
if (!city->getViewMode()) {
|
||||
INFO << cities[city_num] << ": " << city->getCurrentSector()->getFullName() << std::endl <<
|
||||
std::cout << cities[city_num] << ": " << city->getCurrentSector()->getFullName() << std::endl <<
|
||||
"camera.setCenter(" << v.x << ", " << v.y << ", " << v.z << ")" << std::endl <<
|
||||
"camera.setEye(" << e.x << ", " << e.y << ", " << e.z << ")" << std::endl <<
|
||||
"camera.setUp(" << u.x << ", " << u.y << ", " << u.z << ")" << std::endl <<
|
||||
@ -347,7 +507,7 @@ void print_position() {
|
||||
}
|
||||
else {
|
||||
GLfloat* cp = city->getCamPos();
|
||||
INFO << cities[city_num] << ": " << city->getCurrentSector()->getFullName() << std::endl <<
|
||||
std::cout << cities[city_num] << ": " << city->getCurrentSector()->getFullName() << std::endl <<
|
||||
"city_view:setCamPosition(" << cp[0] << ", " << cp[1] << ", " << cp[2] << ")" << std::endl <<
|
||||
"city_view:setVisibleRange(" << city->getVisibleRange() << ")" << std::endl <<
|
||||
"city_view:setTopDownView( true )" << std::endl;
|
||||
@ -389,12 +549,13 @@ void handleKeyUp( SDL_keysym *keysym) {
|
||||
void draw_mapmode();
|
||||
|
||||
void create_ped_at(const Vector3D v) {
|
||||
OpenGTA::Pedestrian p(Vector3D(0.3f, 0.5f, 0.3f), v, 0xffffffff);
|
||||
OpenGTA::Pedestrian p(Vector3D(0.2f, 0.5f, 0.2f), v, 0xffffffff);
|
||||
p.remap = OpenGTA::StyleHolder::Instance().get().getRandomPedRemapNumber();
|
||||
INFO << "using remap: " << p.remap << std::endl;
|
||||
OpenGTA::Pedestrian & pr = OpenGTA::SpriteManagerHolder::Instance().addPed(p);
|
||||
pr.switchToAnim(1);
|
||||
OpenGTA::LocalPlayer::Instance().setCtrl(pr.m_control);
|
||||
GUI::create_ingame_gui(1);
|
||||
//pr.m_control = &OpenGTA::LocalPlayer::Instance();
|
||||
//OpenGTA::SpriteManagerHolder::Instance().getPedById(0xffffffff).giveItem(1, 255);
|
||||
}
|
||||
@ -471,7 +632,7 @@ void add_auto_ped() {
|
||||
v.y += 0.9f;
|
||||
//INFO << v.x << " " << v.y << " " << v.z << std::endl;
|
||||
Sint16 remap = OpenGTA::StyleHolder::Instance().get().getRandomPedRemapNumber();
|
||||
OpenGTA::Pedestrian p(Vector3D(0.3f, 0.5f, 0.3f), v, id, remap);
|
||||
OpenGTA::Pedestrian p(Vector3D(0.2f, 0.5f, 0.2f), v, id, remap);
|
||||
OpenGTA::SpriteManagerHolder::Instance().addPed(p);
|
||||
OpenGTA::Pedestrian & pr2 = OpenGTA::SpriteManagerHolder::Instance().getPedById(id);
|
||||
pr2.switchToAnim(1);
|
||||
@ -486,6 +647,7 @@ void add_auto_ped() {
|
||||
|
||||
void toggle_player_run() {
|
||||
OpenGTA::PedController * pc = &OpenGTA::LocalPlayer::Instance().getCtrl();
|
||||
INFO << std::endl;
|
||||
|
||||
if (!pc) {
|
||||
WARN << "no player yet!" << std::endl;
|
||||
@ -497,6 +659,69 @@ void toggle_player_run() {
|
||||
pc->setRunning(false);
|
||||
}
|
||||
|
||||
void show_gamma_config() {
|
||||
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||
GUI::Manager & gm = GUI::ManagerHolder::Instance();
|
||||
if (gamma_slide) {
|
||||
SDL_Rect r;
|
||||
|
||||
r.x = screen.getWidth() / 2;
|
||||
r.y = screen.getHeight() / 2;
|
||||
r.w = 200;
|
||||
r.h = 30;
|
||||
|
||||
GUI::ScrollBar * sb = new GUI::ScrollBar(GUI::GAMMA_SCROLLBAR_ID, r);
|
||||
sb->color.r = sb->color.g = sb->color.b = 180;
|
||||
sb->color.unused = 255;
|
||||
sb->innerColor.r = 250;
|
||||
sb->value = screen_gamma/2;
|
||||
sb->changeCB = GUI::ScrollBar::SC_Functor(GUI::screen_gamma_callback);
|
||||
gm.add(sb, 90);
|
||||
|
||||
r.y += 40;
|
||||
std::ostringstream os;
|
||||
os << "Gamma: " << screen_gamma;
|
||||
GUI::Label * l = new GUI::Label(GUI::GAMMA_LABEL_ID, r, os.str(), "F_MTEXT.FON", 1);
|
||||
gm.add(l, 80);
|
||||
|
||||
screen.setSystemMouseCursor(true);
|
||||
|
||||
}
|
||||
else {
|
||||
gm.removeById(GUI::GAMMA_SCROLLBAR_ID);
|
||||
gm.removeById(GUI::GAMMA_LABEL_ID);
|
||||
screen.setSystemMouseCursor(false);
|
||||
}
|
||||
}
|
||||
|
||||
void car_toggle() {
|
||||
OpenGTA::Pedestrian & pped = OpenGTA::LocalPlayer::Instance().getPed();
|
||||
Vector3D pos = pped.pos;
|
||||
std::list<OpenGTA::Car> & list = OpenGTA::SpriteManagerHolder::Instance().getList<OpenGTA::Car>();
|
||||
float min_dist = 360;
|
||||
float _d;
|
||||
std::list<OpenGTA::Car>::iterator j = list.end();
|
||||
for (std::list<OpenGTA::Car>::iterator i = list.begin(); i != list.end(); i++) {
|
||||
if ((_d = Util::distance(pos, i->pos)) < min_dist) {
|
||||
j = i;
|
||||
min_dist = _d;
|
||||
}
|
||||
}
|
||||
assert(j != list.end());
|
||||
std::cout << j->id() << " " << j->pos.x << ", " << j->pos.y << ", " << j->pos.z << std::endl;
|
||||
Vector3D p_door(j->carInfo.door[0].rpx / 64.0f, 0,
|
||||
j->carInfo.door[0].rpy / 64.0f);
|
||||
|
||||
Vector3D p_door_global = Transform(p_door, j->m_M);
|
||||
p_door_global.y += 0.2f;
|
||||
std::cout << p_door_global.x << ", " << p_door_global.y << ", " << p_door_global.z << std::endl;
|
||||
test_dot = p_door_global;
|
||||
//pped.aiMode = 1;
|
||||
//pped.aiData.pos1 = p_door_global;
|
||||
OpenGTA::AI::Pedestrian::walk_pavement(&pped);
|
||||
|
||||
}
|
||||
|
||||
void handleKeyPress( SDL_keysym *keysym ) {
|
||||
GLfloat* cp = city->getCamPos();
|
||||
mapPos[0] = cp[0]; mapPos[1] = cp[1]; mapPos[2] = cp[2];
|
||||
@ -530,6 +755,13 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
//zoomToTrain(next_station_zoom++);
|
||||
//if (next_station_zoom >= OpenGTA::SpriteManagerHolder::Instance().trainSystem.getNumTrains())
|
||||
// next_station_zoom = 0;
|
||||
global_Restart = 1;
|
||||
global_Done = 1;
|
||||
return;
|
||||
{
|
||||
Vector3D p(cam.getEye());
|
||||
OpenGTA::MapHolder::Instance().get().getNearestLocationByType(0, p.x, p.z);
|
||||
}
|
||||
break;
|
||||
case SDLK_F2:
|
||||
bbox_toggle = (bbox_toggle ? 0 : 1);
|
||||
@ -558,8 +790,12 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
cam.releaseFollowMode();
|
||||
OpenGTA::SpriteManagerHolder::Instance().removePedById(0xffffffff);
|
||||
OpenGTA::SpriteManagerHolder::Instance().removeDeadStuff();
|
||||
GUI::remove_ingame_gui();
|
||||
}
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
car_toggle();
|
||||
break;
|
||||
case SDLK_F5:
|
||||
draw_arrows = (draw_arrows ? 0 : 1);
|
||||
city->setDrawHeadingArrows(draw_arrows);
|
||||
@ -579,6 +815,10 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
case SDLK_F10:
|
||||
city->setDrawLines(city->getDrawLines() ? 0 : 1);
|
||||
break;
|
||||
case SDLK_F12:
|
||||
gamma_slide = (gamma_slide ? 0 : 1);
|
||||
show_gamma_config();
|
||||
break;
|
||||
case SDLK_LSHIFT:
|
||||
toggle_player_run();
|
||||
break;
|
||||
@ -658,11 +898,16 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
OpenGTA::LocalPlayer::Instance().getCtrl().setMoveBack();
|
||||
break;
|
||||
case 'f':
|
||||
//FIXME: simply ignored on windows for now
|
||||
#ifndef WIN32
|
||||
OpenGL::ScreenHolder::Instance().toggleFullscreen();
|
||||
#endif
|
||||
#if 0
|
||||
#ifdef WIN32
|
||||
city->resetTextures();
|
||||
m_font->resetTextures();
|
||||
//m_font->resetTextures();
|
||||
OpenGL::SpriteCacheHolder::Instance().clearAll();
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
case 'r':
|
||||
@ -723,20 +968,35 @@ void drawScene(Uint32 ticks) {
|
||||
OpenGL::ScreenHolder::Instance().set3DProjection();
|
||||
city->draw(ticks);
|
||||
|
||||
glColor3f(1, 0, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(test_dot.x, test_dot.y, test_dot.z);
|
||||
glEnd();
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
|
||||
OpenGL::ScreenHolder::Instance().setFlatProjection();
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(10, 10, 0);
|
||||
m_font->drawString(city->getCurrentSector()->getFullName());
|
||||
OpenGL::DrawableFont & m_font = OpenGTA::FontCacheHolder::Instance().getFont("F_MTEXT.FON", 1);
|
||||
m_font.drawString(city->getCurrentSector()->getFullName());
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
|
||||
/*glPushMatrix();
|
||||
glTranslatef(5, 50, 0);
|
||||
std::ostringstream strstr;
|
||||
strstr << fps << " fps";
|
||||
m_font->drawString(strstr.str());
|
||||
glPopMatrix();
|
||||
glPopMatrix();*/
|
||||
|
||||
GUI::ManagerHolder::Instance().draw();
|
||||
|
||||
num_frames_drawn += 1;
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
@ -747,9 +1007,9 @@ void draw_mapmode() {
|
||||
bool done_map = false;
|
||||
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||
screen.setSystemMouseCursor(true);
|
||||
GLfloat _scale = 1;
|
||||
GLfloat dx = 0;
|
||||
GLfloat dy = 0;
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
INFO << map_tex.coords[1].u << std::endl;
|
||||
while(!done_map) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
@ -761,31 +1021,20 @@ void draw_mapmode() {
|
||||
case SDLK_ESCAPE:
|
||||
done_map = true;
|
||||
break;
|
||||
case '-':
|
||||
_scale += 0.1f;
|
||||
break;
|
||||
case '+':
|
||||
_scale -= 0.1f;
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
dx -= 0.1f;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
dx += 0.1f;
|
||||
break;
|
||||
case SDLK_UP:
|
||||
dy += 0.1f;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
dy -= 0.1f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
INFO << event.button.x / 600.0f * 255<< " " << event.button.y / 600.0f * 255 << std::endl;
|
||||
mapPos[0] = event.button.x / 600.0f * 255;
|
||||
mapPos[2] = event.button.y / 600.0f * 255;
|
||||
//mapPos[1] = 10;
|
||||
done_map = true;
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
// std::cout << "Mouse move: x " << event.motion.x << " y " <<
|
||||
// event.motion.y << std::endl;
|
||||
std::cout << "Mouse move: x " << event.motion.x << " y " <<
|
||||
event.motion.y << std::endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -796,119 +1045,71 @@ void draw_mapmode() {
|
||||
|
||||
screen.setFlatProjection();
|
||||
glBindTexture(GL_TEXTURE_2D, map_tex.inPage);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glScalef(_scale, _scale, 1);
|
||||
glTranslatef(dx, dy, 0);
|
||||
//glMatrixMode(GL_TEXTURE);
|
||||
//if (_scale < 1)
|
||||
// glScalef(_scale, _scale, 1);
|
||||
|
||||
|
||||
uint32_t h = screen.getHeight();
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(map_tex.coords[0].u, map_tex.coords[0].v);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(0, 0);
|
||||
glTexCoord2f(map_tex.coords[1].u, map_tex.coords[0].v);
|
||||
glVertex2i(screen.getWidth(), 0);
|
||||
glTexCoord2f(map_tex.coords[1].u, 0);
|
||||
glVertex2i(h, 0);
|
||||
glTexCoord2f(map_tex.coords[1].u, map_tex.coords[1].v);
|
||||
glVertex2i(screen.getWidth(), screen.getHeight());
|
||||
glTexCoord2f(map_tex.coords[0].u, map_tex.coords[1].v);
|
||||
glVertex2i(0, screen.getHeight());
|
||||
glVertex2i(h, h);
|
||||
glTexCoord2f(0, map_tex.coords[1].v);
|
||||
glVertex2i(0, h);
|
||||
glEnd();
|
||||
|
||||
const OpenGTA::Map::LocationMap & lmap = OpenGTA::MapHolder::Instance().get().getLocationMap();
|
||||
OpenGTA::Map::LocationMap::const_iterator i = lmap.begin();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
while (i != lmap.end()) {
|
||||
if (i->first == 2) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
uint8_t l_type = i->first;
|
||||
float l_x, l_y;
|
||||
l_x = i->second->x / 255.0f * h;// * map_tex.coords[1].u;
|
||||
l_y = i->second->y / 255.0f * h;// * map_tex.coords[1].u;
|
||||
//INFO << int(l_type) << ": " << l_x << " " << l_y << std::endl;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex2f(l_x - 5, l_y - 5);
|
||||
glVertex2f(l_x + 5, l_y - 5);
|
||||
glVertex2f(l_x + 5, l_y + 5);
|
||||
glVertex2f(l_x - 5, l_y + 5);
|
||||
|
||||
glEnd();
|
||||
++i;
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
SDL_GL_SwapBuffers();
|
||||
SDL_Delay(20);
|
||||
|
||||
}
|
||||
screen.setSystemMouseCursor(false);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
// the texture class doesn't cleanup!
|
||||
glDeleteTextures(1, &map_tex.inPage);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void parse_args(int argc, char* argv[]) {
|
||||
int index;
|
||||
int c;
|
||||
|
||||
opterr = 0;
|
||||
|
||||
#ifdef WITH_LUA
|
||||
#define VIEWER_FLAGS "s:w:h:c:m:g:l:f"
|
||||
#else
|
||||
#define VIEWER_FLAGS "w:h:c:m:g:l:f"
|
||||
#endif
|
||||
while ((c = getopt (argc, argv, VIEWER_FLAGS)) != -1)
|
||||
switch (c)
|
||||
{
|
||||
#ifdef WITH_LUA
|
||||
case 's':
|
||||
script_file = optarg;
|
||||
break;
|
||||
#endif
|
||||
case 'c':
|
||||
highcolor_data = atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
specific_map = std::string(optarg);
|
||||
break;
|
||||
case 'g':
|
||||
specific_style = std::string(optarg);
|
||||
break;
|
||||
case 'w':
|
||||
arg_screen_w = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
arg_screen_h = atoi(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
Util::Log::setOutputLevel(atoi(optarg));
|
||||
break;
|
||||
case 'f':
|
||||
full_screen = true;
|
||||
break;
|
||||
case '?':
|
||||
if (isprint (optopt))
|
||||
ERROR << "Unknown option `-" << char(optopt) << "'" << std::endl;
|
||||
else
|
||||
ERROR << "Unknown option character `" << optopt << "'" << std::endl;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
for (index = optind; index < argc; index++)
|
||||
city_num = atoi(argv[index]);
|
||||
|
||||
if (city_num > 2) {
|
||||
ERROR << "Invalid city number: " << city_num << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void run_init(const char* prgname) {
|
||||
PHYSFS_init("mapview");
|
||||
//PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||
Util::FileHelper & fh = GET_FILE_HELPER;
|
||||
if (fh.existsInSystemFS(fh.getBaseDataPath()))
|
||||
PHYSFS_addToSearchPath(GET_FILE_HELPER.getBaseDataPath().c_str(), 1);
|
||||
else {
|
||||
WARN << "Could not load data-source: " << fh.getBaseDataPath() <<" -- fallback to current directory"<< std::endl;
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
}
|
||||
if (fh.existsInSystemFS(fh.getModDataPath()))
|
||||
PHYSFS_addToSearchPath(GET_FILE_HELPER.getModDataPath().c_str(), 0);
|
||||
|
||||
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||
screen.setFullScreenFlag(full_screen);
|
||||
screen.activate(arg_screen_w, arg_screen_h);
|
||||
//SDL_EnableKeyRepeat( 100, SDL_DEFAULT_REPEAT_INTERVAL );
|
||||
}
|
||||
#endif
|
||||
|
||||
void run_main() {
|
||||
SDL_Event event;
|
||||
OpenGTA::MainMsgHolder::Instance().load("ENGLISH.FXT");
|
||||
const char * lang = getenv("OGTA_LANG");
|
||||
if (!lang)
|
||||
lang = getenv("LANG");
|
||||
if (!lang)
|
||||
lang = "en";
|
||||
OpenGTA::MainMsgHolder::Instance().load(Util::FileHelper::lang2MsgFilename(lang));
|
||||
|
||||
m_font = new OpenGL::DrawableFont();
|
||||
m_font->loadFont("F_MTEXT.FON");
|
||||
m_font->setScale(1);
|
||||
//m_font = new OpenGL::DrawableFont();
|
||||
//m_font->loadFont("F_MTEXT.FON");
|
||||
//m_font->setScale(1);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
@ -917,7 +1118,7 @@ void run_main() {
|
||||
//glEnable(GL_BLEND);
|
||||
//glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0);
|
||||
glAlphaFunc(GL_GREATER, 2/255.0f);//0);
|
||||
|
||||
city = new OpenGTA::CityView();
|
||||
if (specific_map.size() > 0 && specific_style.size() > 0) {
|
||||
@ -929,13 +1130,14 @@ void run_main() {
|
||||
else
|
||||
city->loadMap(cities[city_num], styles_8[city_num]);
|
||||
}
|
||||
if (city_blocks_area > -1)
|
||||
city->setVisibleRange(city_blocks_area);
|
||||
city->setPosition(mapPos[0], mapPos[1], mapPos[2]);
|
||||
|
||||
OpenGL::Camera & cam = OpenGL::CameraHolder::Instance();
|
||||
//cam.setVectors( Vector3D(4, 10, 4), Vector3D(4, 0.0f, 4.0f), Vector3D(0, 0, -1) );
|
||||
cam.setVectors( Vector3D(12, 20, 12), Vector3D(13.0f, 19.0f, 13.0f), Vector3D(0, 1, 0) );
|
||||
|
||||
|
||||
#ifdef TIMER_OPENSTEER_CLOCK
|
||||
Timer & timer = TimerHolder::Instance();
|
||||
timer.update();
|
||||
@ -948,13 +1150,14 @@ void run_main() {
|
||||
#ifdef WITH_LUA
|
||||
OpenGTA::Script::LuaVM & vm = OpenGTA::Script::LuaVMHolder::Instance();
|
||||
vm.setCityView(*city);
|
||||
vm.setMap(OpenGTA::MapHolder::Instance().get());
|
||||
if (script_file)
|
||||
vm.runFile(script_file);
|
||||
//vm.runString("function game_tick() print('tick...') end");
|
||||
bool vm_tick_ok = true;
|
||||
script_last_tick = last_tick;
|
||||
#endif
|
||||
|
||||
GUI::Manager & guiManager = GUI::ManagerHolder::Instance();
|
||||
|
||||
while(!global_Done && !global_EC) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
@ -980,6 +1183,9 @@ void run_main() {
|
||||
case SDL_MOUSEMOTION:
|
||||
//std::cout << "Mouse move: x " << float(event.motion.x)/screen->w << " y " << float(event.motion.y)/screen->h << std::endl;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
guiManager.receive(event.button);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -992,6 +1198,8 @@ void run_main() {
|
||||
#endif
|
||||
OpenGTA::SpriteManagerHolder::Instance().update(now_ticks);
|
||||
city->blockAnims->update(now_ticks);
|
||||
GUI::ManagerHolder::Instance().update(now_ticks);
|
||||
GUI::update_ingame_gui_values();
|
||||
if (!paused) {
|
||||
drawScene(now_ticks - last_tick);
|
||||
last_tick = now_ticks;
|
||||
@ -1018,9 +1226,19 @@ void run_main() {
|
||||
fps = num_frames_drawn / 2;
|
||||
num_frames_drawn = 0;
|
||||
fps_last_tick = now_ticks;
|
||||
std::ostringstream os;
|
||||
os << fps << " fps";
|
||||
fps_label->text = os.str();
|
||||
#ifdef WITH_LUA
|
||||
vm.setGlobalInt("current_fps", fps);
|
||||
#endif
|
||||
}
|
||||
//#endif
|
||||
// SDL_Delay(10);
|
||||
}
|
||||
|
||||
#ifdef WITH_LUA
|
||||
vm.runFile("scripts/dump_config.lua");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user